Skip to content

Commit

Permalink
NQuadsParser: detect parsing errors correctly
Browse files Browse the repository at this point in the history
While this commit makes the reason of
#7 to be clearly reported
it doesn't solve the problem of the PREG_JIT_STACKLIMIT_ERROR
  • Loading branch information
zozlak committed Apr 13, 2024
1 parent 5a1fa15 commit c492605
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
26 changes: 13 additions & 13 deletions src/quickRdfIo/NQuadsParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ private function quadGenerator(): Generator {
$n++;
$this->line = $this->readLine();
$ret = preg_match($this->regexp, $this->line, $matches, PREG_UNMATCHED_AS_NULL);
if ($ret === 0 && !empty(trim($this->line))) {
throw new RdfIoException("Can't parse line $n: " . $this->line);
if (0 === (int) $ret && !empty(trim($this->line))) {
throw new RdfIoException("Can't parse line $n with error '" . preg_last_error_msg() . "': " . $this->line);
}
if (($matches[3] ?? null) !== null) {
yield $this->makeQuad($matches);
Expand Down Expand Up @@ -320,10 +320,10 @@ private function starQuadGenerator(): Generator {
$this->level = 0;
$this->line = $this->readLine();
try {
yield $this->parseStar();
yield $this->parseStar($n);
} catch (RdfIoException $e) {
$ret = preg_match($this->regexpCommentLine, $this->line);
if ($ret === 0) {
if (0 === (int) $ret) {
throw $e;
}
}
Expand All @@ -333,23 +333,23 @@ private function starQuadGenerator(): Generator {
}
}

private function parseStar(): iQuad {
private function parseStar(int $line): iQuad {
//echo str_repeat("\t", $this->level) . "parsing " . substr($this->line, $this->offset);
$matches = null;
if (preg_match(self::STAR_START, $this->line, $matches, 0, $this->offset)) {
$this->offset += strlen($matches[0]);
$this->level++;
$sbj = $this->parseStar();

Check failure on line 342 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Method quickRdfIo\NQuadsParser::parseStar() invoked with 0 parameters, 1 required.
$ret = preg_match($this->regexpPred, $this->line, $matches, PREG_UNMATCHED_AS_NULL, $this->offset);
if ($ret === 0) {
throw new RdfIoException("Failed parsing predicate " . substr($this->line, $this->offset));
if (0 === (int) $ret) {
throw new RdfIoException("Failed parsing predicate on line $line with error '" . preg_last_error_msg() . "': " . substr($this->line, $this->offset));
}
$this->offset += strlen($matches[0]);

Check failure on line 347 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.
$pred = $this->dataFactory::namedNode($matches[1]);

Check failure on line 348 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $iri of static method rdfInterface\DataFactoryInterface::namedNode() expects string|Stringable, string|null given.
} else {
$ret = preg_match($this->regexpSbjPred, $this->line, $matches, PREG_UNMATCHED_AS_NULL, $this->offset);
if ($ret === 0) {
throw new RdfIoException("Failed parsing subject and predicate " . substr($this->line, $this->offset));
if (0 === (int) $ret) {
throw new RdfIoException("Failed parsing subject and predicate on line $line with error '" . preg_last_error_msg() . "': " . substr($this->line, $this->offset));
}
$this->offset += strlen($matches[0]);

Check failure on line 354 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.
if ($matches[1] !== null) {
Expand All @@ -372,8 +372,8 @@ private function parseStar(): iQuad {
}
} else {
$ret = preg_match($this->regexpObjGraph, $this->line, $matches, PREG_UNMATCHED_AS_NULL, $this->offset);
if ($ret === 0) {
throw new RdfIoException("Can't parse object " . substr($this->line, $this->offset));
if (0 === (int) $ret) {
throw new RdfIoException("Can't parse object on line $line with error '" . preg_last_error_msg() . "': " . substr($this->line, $this->offset));
}
$this->offset += strlen($matches[0]);

Check failure on line 378 in src/quickRdfIo/NQuadsParser.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $string of function strlen expects string, string|null given.
if ($matches[1] !== null) {
Expand All @@ -393,8 +393,8 @@ private function parseStar(): iQuad {
}
$regexpEnd = $this->level > 0 ? self::STAR_END : $this->regexpLineEnd;
$ret = preg_match($regexpEnd, $this->line, $matches, 0, $this->offset);
if ($ret === 0) {
throw new RdfIoException("Can't parse end " . substr($this->line, $this->offset));
if (0 === (int) $ret) {
throw new RdfIoException("Can't parse end on line $line with error '" . preg_last_error_msg() . "': " . substr($this->line, $this->offset));
}
$this->offset += strlen($matches[0]);
$quad = $this->dataFactory::quad($sbj, $pred, $obj, $graph ?? null);
Expand Down
14 changes: 13 additions & 1 deletion tests/NQuadsParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,4 +249,16 @@ public function testInputExceptions(): void {
$this->assertEquals('Input has to be a resource or Psr\Http\Message\StreamInterface object', $ex->getMessage());
}
}
}

/**
* https://github.com/sweetrdf/quickRdfIo/issues/7
*/
public function testIssue7(): void {
$input = __DIR__ . '/files/issue7.nt';

$parser = new NQuadsParser(new DF(), false, NQuadsParser::MODE_TRIPLES);
$this->assertCount(2, iterator_to_array($parser->parseStream(fopen($input, 'r'))));

$parser = new NQuadsParser(new DF(), false, NQuadsParser::MODE_TRIPLES_STAR);
$this->assertCount(2, iterator_to_array($parser->parseStream(fopen($input, 'r'))));
}}

0 comments on commit c492605

Please sign in to comment.