Skip to content

Commit

Permalink
-Fixed invalid schema ids during discovery
Browse files Browse the repository at this point in the history
-Fixed error message when resolving a non-URI schema reference
  • Loading branch information
JamesNK committed Aug 29, 2015
1 parent 6d46cf7 commit 5c07ffa
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Build/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
$zipFileName = "JsonSchema10r11.zip"
$majorVersion = "1.0"
$majorWithReleaseVersion = "1.0.11"
$nugetPrelease = "beta5"
$nugetPrelease = $null
$version = GetVersion $majorWithReleaseVersion
$packageId = "Newtonsoft.Json.Schema"
$signAssemblies = $false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,5 +516,156 @@ public void DuplicateIds()
Assert.AreEqual("duplicate", discovery.KnownSchemas[3].Id.OriginalString);
Assert.AreEqual("duplicate#/properties/test", discovery.KnownSchemas[4].Id.OriginalString);
}

[Test]
public void InvalidSchemaId()
{
string schemaJson = @"{
""id"": ""#root"",
""$schema"": ""http://json-schema.org/draft-04/schema#"",
""title"": ""command"",
""type"": ""object"",
""oneOf"": [
{
""$ref"": ""#/definitions/registerCommand""
},
{
""$ref"": ""#/definitions/unregisterCommand""
},
{
""$ref"": ""#/definitions/loginCommand""
},
{
""$ref"": ""#/definitions/logoutCommand""
},
{
""$ref"": ""#/definitions/syncCommand""
},
{
""$ref"": ""#/definitions/sendmsgCommand""
}
],
""required"": [
""cmd""
],
""definitions"": {
""registerCommand"": {
""properties"": {
""cmd"": {
""enum"": [
""register""
]
},
""pms"": {
""$ref"": ""#/definitions/authParams""
}
},
""required"": [
""pms""
]
},
""unregisterCommand"": {
""properties"": {
""cmd"": {
""enum"": [
""unregister""
]
}
}
},
""loginCommand"": {
""title"": ""log in"",
""properties"": {
""cmd"": {
""enum"": [
""login""
]
},
""pms"": {
""$ref"": ""#/definitions/authParams""
}
},
""required"": [
""pms""
]
},
""logoutCommand"": {
""title"": ""log out"",
""properties"": {
""cmd"": {
""enum"": [
""logout""
]
}
}
},
""syncCommand"": {
""properties"": {
""cmd"": {
""enum"": [
""sync""
]
},
""pms"": {
""$ref"": ""#/definitions/syncParams""
}
},
""required"": [
""pms""
]
},
""sendmsgCommand"": {
""properties"": {
""cmd"": {
""enum"": [
""sendmsg""
]
},
""pms"": {
}
},
""required"": [
""pms""
]
},
""authParams"": {
""type"": ""object"",
""properties"": {
""username"": {
},
""password"": {
}
},
""required"": [
""username"",
""password""
]
},
""syncParams"": {
""type"": ""object"",
""properties"": {
""inbox"": {
},
""contacts"": {
}
},
""required"": [
""inbox"",
""contacts""
]
}
}
}";

JSchemaReader schemaReader = new JSchemaReader(new JSchemaReaderSettings());
schemaReader.ReadRoot(new JsonTextReader(new StringReader(schemaJson)));

JSchemaDiscovery discovery = schemaReader._schemaDiscovery;

foreach (KnownSchema knownSchema in discovery.KnownSchemas)
{
Assert.IsFalse(knownSchema.Id.OriginalString.StartsWith("#/#/", StringComparison.Ordinal));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2823,7 +2823,28 @@ public void InvalidId()
ExceptionAssert.Throws<JSchemaReaderException>(() =>
{
JSchema.Parse(schemaJson);
}, "Error parsing id 'http://'. Id must be a valid URI.");
}, "Error parsing id 'http://'. Id must be a valid URI. Path 'id', line 3, position 18.");
}

[Test]
public void InvalidSchemaId()
{
string schemaJson = @"{
""id"": ""#root"",
""$schema"": ""http://json-schema.org/draft-04/schema#"",
""title"": ""command"",
""type"": ""object"",
""oneOf"": [
{
""$ref"": ""file:system.json#/definitions/username""
}
]
}";

ExceptionAssert.Throws<JSchemaReaderException>(() =>
{
JSchema.Parse(schemaJson);
}, "Error resolving schema reference 'file:system.json#/definitions/username' in the scope '#root'. The resolved reference must be a valid URI. Path 'oneOf[0]', line 7, position 6.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ private Uri GetSchemaIdAndNewScopeId(JSchema schema, ref string latestPath, out
currentPath = StringHelpers.Join("/", _pathStack.Where(p => p.Id == currentScopeId && !string.IsNullOrEmpty(p.Path)).Reverse().Select(p => p.Path));

if (!string.IsNullOrEmpty(currentScopeId.OriginalString)
&& currentPath != "#"
&& !currentPath.StartsWith("#/", StringComparison.Ordinal))
&& !currentPath.StartsWith("#", StringComparison.Ordinal))
{
currentPath = "#/" + currentPath;
}
Expand Down Expand Up @@ -146,10 +145,32 @@ private Uri GetSchemaIdAndNewScopeId(JSchema schema, ref string latestPath, out
}
}

Uri schemaKnownId = SchemaDiscovery.ResolveSchemaIdAndScopeId(_pathStack.First().Id, schema.Id, currentPath, out newScopeId);
Uri schemaKnownId = ResolveSchemaIdAndScopeId(currentScopeId, schema.Id, currentPath, out newScopeId);
return schemaKnownId;
}

public static Uri ResolveSchemaIdAndScopeId(Uri idScope, Uri schemaId, string path, out Uri newScope)
{
Uri knownSchemaId;
if (schemaId != null)
{
newScope = SchemaDiscovery.ResolveSchemaId(idScope, schemaId);

knownSchemaId = newScope;
}
else
{
if (idScope == null)
knownSchemaId = new Uri(path, UriKind.RelativeOrAbsolute);
else
knownSchemaId = SchemaDiscovery.ResolveSchemaId(idScope, new Uri(path, UriKind.RelativeOrAbsolute));

newScope = idScope;
}

return knownSchemaId;
}

private void DiscoverTokenSchemas(string name, JToken token)
{
if (token is JObject)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,13 @@ public static bool FindSchema(Action<JSchema> setSchema, JSchema schema, Uri roo
{
JSchema inlineSchema = schemaReader.ReadInlineSchema(setSchema, t);

discovery.Discover(inlineSchema, rootSchemaId, reference.OriginalString);
string path = reference.OriginalString;
if (path.StartsWith("#/", StringComparison.Ordinal))
{
path = path.Substring(2, path.Length - 2);
}

discovery.Discover(inlineSchema, rootSchemaId, path);

resolvedSchema = true;
}
Expand Down Expand Up @@ -250,28 +256,6 @@ public static bool FindSchema(Action<JSchema> setSchema, JSchema schema, Uri roo
return resolvedSchema;
}

public static Uri ResolveSchemaIdAndScopeId(Uri idScope, Uri schemaId, string path, out Uri newScope)
{
Uri knownSchemaId;
if (schemaId != null)
{
newScope = ResolveSchemaId(idScope, schemaId);

knownSchemaId = newScope;
}
else
{
if (idScope == null)
knownSchemaId = new Uri(path, UriKind.RelativeOrAbsolute);
else
knownSchemaId = ResolveSchemaId(idScope, new Uri(path, UriKind.RelativeOrAbsolute));

newScope = idScope;
}

return knownSchemaId;
}

public static Uri ResolveSchemaId(Uri idScope, Uri schemaId)
{
if (idScope == null || schemaId.IsAbsoluteUri)
Expand Down
13 changes: 11 additions & 2 deletions Src/Newtonsoft.Json.Schema/Infrastructure/JSchemaReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ private Uri ReadUri(JsonReader reader, string name)
}
catch (Exception ex)
{
throw new JSchemaReaderException("Error parsing id '{0}'. Id must be a valid URI.".FormatWith(CultureInfo.InvariantCulture, id), ex);
throw JSchemaReaderException.Create(reader, _baseUri, "Error parsing id '{0}'. Id must be a valid URI.".FormatWith(CultureInfo.InvariantCulture, id), ex);
}
}

Expand Down Expand Up @@ -851,7 +851,16 @@ private Uri ResolveSchemaReference(JSchema schema)
}
}

resolvedReference = SchemaDiscovery.ResolveSchemaId(resolvedReference, schema.Reference);
try
{
resolvedReference = SchemaDiscovery.ResolveSchemaId(resolvedReference, schema.Reference);
}
catch (Exception ex)
{
string message = "Error resolving schema reference '{0}' in the scope '{1}'. The resolved reference must be a valid URI.".FormatWith(CultureInfo.InvariantCulture, schema.Reference, resolvedReference);
throw JSchemaReaderException.Create(schema, _baseUri, schema.Path, message, ex);
}

return resolvedReference;
}

Expand Down

0 comments on commit 5c07ffa

Please sign in to comment.