Skip to content

Commit 2c244a9

Browse files
committed
#282 Added checks for invalid newlines and duplicated entries
1 parent 5c4dfd3 commit 2c244a9

1 file changed

Lines changed: 21 additions & 0 deletions

File tree

src/Loader/StrictPoLoader.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ private function newEntry(): void
6161
*/
6262
private function saveEntry(): void
6363
{
64+
if ($this->translations->getTranslations()[$this->translation->getId()] ?? null) {
65+
throw new Exception("Duplicated entry at byte {$this->position}");
66+
}
6467
$this->translations->add($this->translation);
6568
}
6669

@@ -328,6 +331,7 @@ private function readContext(): bool
328331
private function readOriginal(): void
329332
{
330333
$data = $this->readIdentifier('msgid', true);
334+
$this->checkNewLine($data, 'msgid');
331335
$this->translation = $this->translation->withOriginal($data);
332336
}
333337

@@ -339,6 +343,7 @@ private function readPlural(): bool
339343
if (($data = $this->readIdentifier('msgid_plural')) === null) {
340344
return false;
341345
}
346+
$this->checkNewLine($data, 'msgid_plural');
342347
$this->translation->setPlural($data);
343348

344349
return true;
@@ -355,6 +360,10 @@ private function readTranslation(): void
355360
}
356361
$this->readWhiteSpace();
357362
$data = $this->readQuotedString();
363+
// The header might be surrounded by newlines
364+
if ($this->translation->getOriginal() !== '') {
365+
$this->checkNewLine($data, 'msgstr');
366+
}
358367
$this->translation->translate($data);
359368
}
360369

@@ -392,6 +401,7 @@ private function readPluralTranslation(bool $throwIfNotFound = false): bool
392401
$this->readWhiteSpace();
393402
$data = $this->readQuotedString();
394403
$translations[] = $data;
404+
$this->checkNewLine($data, 'msgstr');
395405
$this->translation->translate(array_shift($translations));
396406
$this->translation->translatePlural(...$translations);
397407

@@ -452,4 +462,15 @@ private function readHeaders(?string $string): array
452462

453463
return $headers;
454464
}
465+
466+
/**
467+
* Ensures the data doesn't start nor end with a newline
468+
*/
469+
private function checkNewLine(string $data, string $context): void
470+
{
471+
if (($first = substr($data, 0, 1)) === "\n" || $first === "\r"
472+
|| ($last = substr($data, -1)) === "\n" || $last === "\n") {
473+
throw new Exception("$context cannot start nor end with a newline at byte {$this->position}");
474+
}
475+
}
455476
}

0 commit comments

Comments
 (0)