lanthaler / JsonLD

JSON-LD processor for PHP
MIT License
335 stars 62 forks source link

Schema with duplicate value causes infinite loop #87

Open dochne opened 6 years ago

dochne commented 6 years ago

If the @id of a schema and the value of another field (say, url) are identical, parsing the document will result in a stack overflow.

It looks like this is caused by Nodes being keyed by the value of the node, but I'm enough of a layman to be unsure as to: a. whether there was a good reason to do it in the first place b. if there is a good way to fix and c. if it's even allowable by the JSON-LD spec (I would assume it is, but again, I'm not intricately familiar with it)

I'm willing to put in the effort to try and get this fixed, but I'd need some guidance about what should be done to do so.

Example JSON-LD:

{
  "@context": "http://schema.org/",
  "@type": "Website",
  "@id": "https://www.example.com/",
  "url": "https://www.example.com/"
}

Example test script:

include("vendor/autoload.php");

$class = new stdClass;
$class->{'@context'} = "http://schema.org/";
$class->{'@type'} = "Website";
$class->{'@id'} = "https://www.example.com/";
$class->{'url'} = "https://www.example.com/";

$graph = \ML\JsonLD\JsonLD::getDocument($class)->getGraph();

function iterateNodes(array $nodes, $maxDepth = 10, $prefix = "")
{
    if ($maxDepth === 0) {
        echo "Hit MaxDepth\n";
        return;
    }

    /**
     * @var \ML\JsonLD\Node $node
     */
    foreach ($nodes as $node) {
        echo $prefix . "ID: ".$node->getId()."\n";
        /**
         * @var \ML\JsonLD\Node[] $properties
         */
        $properties = $node->getProperties();
        iterateNodes($properties, $maxDepth - 1, $prefix . "  ");
    }
}

iterateNodes($graph->getNodes());

Expected output:

ID: https://www.example.com/
  ID: http://schema.org/Website
  ID: https://www.example.com
ID: http://schema.org/Website
ID: https://www.example.com/

Actual output:

ID: https://www.example.com/
  ID: http://schema.org/Website
  ID: https://www.example.com/
    ID: http://schema.org/Website
    ID: https://www.example.com/
      ID: http://schema.org/Website
      ID: https://www.example.com/
        ID: http://schema.org/Website
        ID: https://www.example.com/
          ID: http://schema.org/Website
          ID: https://www.example.com/
            ID: http://schema.org/Website
            ID: https://www.example.com/
              ID: http://schema.org/Website
              ID: https://www.example.com/
                ID: http://schema.org/Website
                ID: https://www.example.com/
                  ID: http://schema.org/Website
Hit MaxDepth
                  ID: https://www.example.com/
Hit MaxDepth
ID: http://schema.org/Website
Sarke commented 4 years ago

https://github.com/jkphl/micrometa/pull/56