Fix remote document loading bugs.

This commit is contained in:
Dave Longley 2013-09-14 14:12:19 -04:00
parent 42041d08c7
commit 4685958cbf

View file

@ -839,7 +839,7 @@ class JsonLdProcessor {
// if input is a string, attempt to dereference remote document // if input is a string, attempt to dereference remote document
if(is_string($input)) { if(is_string($input)) {
$remote_doc = $options['documentLoader']($input); $remote_doc = call_user_func($options['documentLoader'], $input);
} }
else { else {
$remote_doc = (object)array( $remote_doc = (object)array(
@ -848,9 +848,26 @@ class JsonLdProcessor {
'document' => $input); 'document' => $input);
} }
try {
if($remote_doc->document === null) {
throw new JsonLdException(
'No remote document found at the given URL.',
'jsonld.NullRemoteDocument');
}
if(is_string($remote_doc->document)) {
$remote_doc->document = _parse_json($remote_doc->document);
}
}
catch(Exception $e) {
throw new JsonLdException(
'Could not retrieve a JSON-LD document from the URL.',
'jsonld.LoadDocumentError', 'loading document failed',
array('remoteDoc' => $remote_doc), $e);
}
// build meta-object and retrieve all @context urls // build meta-object and retrieve all @context urls
$input = (object)array( $input = (object)array(
'document' => self::copy($input), 'document' => self::copy($remote_doc->document),
'remoteContext' => (object)array( 'remoteContext' => (object)array(
'@context' => $remote_doc->contextUrl)); '@context' => $remote_doc->contextUrl));
if(isset($options['expandContext'])) { if(isset($options['expandContext'])) {
@ -981,7 +998,7 @@ class JsonLdProcessor {
// if frame is a string, attempt to dereference remote document // if frame is a string, attempt to dereference remote document
if(is_string($frame)) { if(is_string($frame)) {
$remote_frame = $options['documentLoader']($frame); $remote_frame = call_user_func($options['documentLoader'], $frame);
} }
else { else {
$remote_frame = (object)array( $remote_frame = (object)array(
@ -990,6 +1007,23 @@ class JsonLdProcessor {
'document' => $frame); 'document' => $frame);
} }
try {
if($remote_frame->document === null) {
throw new JsonLdException(
'No remote document found at the given URL.',
'jsonld.NullRemoteDocument');
}
if(is_string($remote_frame->document)) {
$remote_frame->document = _parse_json($remote_frame->document);
}
}
catch(Exception $e) {
throw new JsonLdException(
'Could not retrieve a JSON-LD document from the URL.',
'jsonld.LoadDocumentError', 'loading document failed',
array('remoteDoc' => $remote_doc), $e);
}
// preserve frame context // preserve frame context
$frame = $remote_frame->document; $frame = $remote_frame->document;
if($frame !== null) { if($frame !== null) {
@ -5056,36 +5090,14 @@ class JsonLdProcessor {
// parse string context as JSON // parse string context as JSON
if(is_string($ctx)) { if(is_string($ctx)) {
$ctx = json_decode($ctx); try {
switch(json_last_error()) { $ctx = _parse_json($ctx);
case JSON_ERROR_NONE: }
break; catch(Exception $e) {
case JSON_ERROR_DEPTH: throw new JsonLdException(
throw new JsonLdException( 'Could not parse JSON from URL.',
'Could not parse JSON from URL; the maximum stack depth has ' . 'jsonld.ParseError', 'invalid remote context',
'been exceeded.', 'jsonld.ParseError', 'invalid remote context', array('url' => $url), $e);
array('url' => $url));
case JSON_ERROR_STATE_MISMATCH:
throw new JsonLdException(
'Could not parse JSON from URL; invalid or malformed JSON.',
'jsonld.ParseError', 'invalid remote context',
array('url' => $url));
case JSON_ERROR_CTRL_CHAR:
case JSON_ERROR_SYNTAX:
throw new JsonLdException(
'Could not parse JSON from URL; syntax error, malformed JSON.',
'jsonld.ParseError', 'invalid remote context',
array('url' => $url));
case JSON_ERROR_UTF8:
throw new JsonLdException(
'Could not parse JSON from URL; malformed UTF-8 characters.',
'jsonld.ParseError', 'invalid remote context',
array('url' => $url));
default:
throw new JsonLdException(
'Could not parse JSON from URL; unknown error.',
'jsonld.ParseError', 'invalid remote context',
array('url' => $url));
} }
} }
@ -5478,6 +5490,43 @@ class JsonLdProcessor {
} }
return !property_exists($o2, $key); return !property_exists($o2, $key);
} }
/**
* Parses JSON and sets an appropriate exception message on error.
*
* @param string $json the JSON to parse.
*
* @return mixed the parsed JSON object or array.
*/
protected static function _parse_json($json) {
$rval = json_decode($json);
switch(json_last_error()) {
case JSON_ERROR_NONE:
break;
case JSON_ERROR_DEPTH:
throw new JsonLdException(
'Could not parse JSON; the maximum stack depth has been exceeded.',
'jsonld.ParseError');
case JSON_ERROR_STATE_MISMATCH:
throw new JsonLdException(
'Could not parse JSON; invalid or malformed JSON.',
'jsonld.ParseError');
case JSON_ERROR_CTRL_CHAR:
case JSON_ERROR_SYNTAX:
throw new JsonLdException(
'Could not parse JSON; syntax error, malformed JSON.',
'jsonld.ParseError');
case JSON_ERROR_UTF8:
throw new JsonLdException(
'Could not parse JSON from URL; malformed UTF-8 characters.',
'jsonld.ParseError');
default:
throw new JsonLdException(
'Could not parse JSON from URL; unknown error.',
'jsonld.ParseError');
}
return $rval;
}
} }
// register the N-Quads RDF parser // register the N-Quads RDF parser