Beispiel #1
0
        protected ValidationError CreateError(string message, ErrorType errorType, JSchema schema, object value, IList <ValidationError> childErrors, IJsonLineInfo lineInfo, string path)
        {
            if (_schemaDiscovery == null)
            {
                _schemaDiscovery = new JSchemaDiscovery();
                _schemaDiscovery.Discover(Schema, null);
            }

            Uri schemaId = _schemaDiscovery.KnownSchemas.Single(s => s.Schema == schema).Id;

            ValidationError error = ValidationError.CreateValidationError(message, errorType, schema, schemaId, value, childErrors, lineInfo, path);

            return(error);
        }
Beispiel #2
0
        public void SerializeError()
        {
            ValidationError error = ValidationError.CreateValidationError(
                message: $"A message!",
                errorType: ErrorType.MinimumLength,
                schema: new JSchema
            {
                BaseUri = new Uri("test.xml", UriKind.RelativeOrAbsolute),
                Type    = JSchemaType.Number
            },
                schemaId: new Uri("test.xml", UriKind.RelativeOrAbsolute),
                value: "A value!",
                childErrors: new List <ValidationError>
            {
                ValidationError.CreateValidationError($"Child message!", ErrorType.None, new JSchema(), null, null, null, null, null)
            },
                lineInfo: new DummyLineInfo(),
                path: "sdf.sdf");

            string json = JsonConvert.SerializeObject(error, Formatting.Indented);

            StringAssert.AreEqual(@"{
  ""Message"": ""A message!"",
  ""LineNumber"": 11,
  ""LinePosition"": 5,
  ""Path"": ""sdf.sdf"",
  ""Value"": ""A value!"",
  ""SchemaId"": ""test.xml"",
  ""SchemaBaseUri"": ""test.xml"",
  ""ErrorType"": ""minLength"",
  ""ChildErrors"": [
    {
      ""Message"": ""Child message!"",
      ""LineNumber"": 0,
      ""LinePosition"": 0,
      ""Path"": null,
      ""Value"": null,
      ""SchemaId"": null,
      ""SchemaBaseUri"": null,
      ""ErrorType"": ""none"",
      ""ChildErrors"": []
    }
  ]
}", json);
        }
        protected ValidationError CreateError(IFormattable message, ErrorType errorType, JSchema schema, object value, IList <ValidationError> childErrors, IJsonLineInfo lineInfo, string path)
        {
            ValidationError error = ValidationError.CreateValidationError(message, errorType, schema, null, value, childErrors, lineInfo, path);

            return(error);
        }
Beispiel #4
0
        private void ProcessSchemaName(ref JsonReader reader, bool isRoot, JSchema schema, string name)
        {
            switch (name)
            {
            case Constants.PropertyNames.Id:
                schema.Id = ReadUri(reader, name);
                break;

            case Constants.PropertyNames.Ref:
                schema.Reference = ReadUri(reader, name);
                break;

            case Constants.PropertyNames.Properties:
                schema._properties = ReadProperties(reader);

                // add schemas with deprecated required flag to new required array
                foreach (KeyValuePair <string, JSchema> schemaProperty in schema.Properties)
                {
                    if (schemaProperty.Value.DeprecatedRequired)
                    {
                        if (!schema.Required.Contains(schemaProperty.Key))
                        {
                            schema.Required.Add(schemaProperty.Key);
                        }
                    }
                }
                break;

            case Constants.PropertyNames.Items:
                ReadItems(reader, schema);
                break;

            case Constants.PropertyNames.Type:
            {
                object typeResult = ReadType(reader, name);
                if (typeResult is JSchemaType)
                {
                    schema.Type = (JSchemaType)typeResult;
                }
                else
                {
                    schema._anyOf = (List <JSchema>)typeResult;
                }
                break;
            }

            case Constants.PropertyNames.AnyOf:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    ReadSchemaArray(reader, name, out schema._anyOf);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.AllOf:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    ReadSchemaArray(reader, name, out schema._allOf);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.OneOf:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    ReadSchemaArray(reader, name, out schema._oneOf);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.Not:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    ReadSchema(reader, name, s => schema.Not = s);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.Title:
                schema.Title = ReadString(reader, name);
                break;

            case Constants.PropertyNames.Description:
                schema.Description = ReadString(reader, name);
                break;

            case Constants.PropertyNames.Format:
                schema.Format = ReadString(reader, name);
                break;

            case Constants.PropertyNames.AdditionalProperties:
                ReadAdditionalProperties(reader, schema);
                break;

            case Constants.PropertyNames.AdditionalItems:
                ReadAdditionalItems(reader, schema);
                break;

            case Constants.PropertyNames.PatternProperties:
                schema._patternProperties = ReadProperties(reader);
                break;

            case Constants.PropertyNames.Required:
                ReadRequired(reader, schema);
                break;

            case Constants.PropertyNames.Dependencies:
                ReadDependencies(reader, schema);
                break;

            case Constants.PropertyNames.Minimum:
                schema.Minimum = ReadDouble(reader, name);
                break;

            case Constants.PropertyNames.Maximum:
                schema.Maximum = ReadDouble(reader, name);
                break;

            case Constants.PropertyNames.ExclusiveMinimum:
                schema.ExclusiveMinimum = ReadBoolean(reader, name);
                break;

            case Constants.PropertyNames.ExclusiveMaximum:
                schema.ExclusiveMaximum = ReadBoolean(reader, name);
                break;

            case Constants.PropertyNames.MaximumLength:
                schema.MaximumLength = ReadInteger(reader, name);
                break;

            case Constants.PropertyNames.MinimumLength:
                schema.MinimumLength = ReadInteger(reader, name);
                break;

            case Constants.PropertyNames.MaximumItems:
                schema.MaximumItems = ReadInteger(reader, name);
                break;

            case Constants.PropertyNames.MinimumItems:
                schema.MinimumItems = ReadInteger(reader, name);
                break;

            case Constants.PropertyNames.MaximumProperties:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    schema.MaximumProperties = ReadInteger(reader, name);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.MinimumProperties:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    schema.MinimumProperties = ReadInteger(reader, name);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.DivisibleBy:
                if (EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3))
                {
                    schema.MultipleOf = ReadDouble(reader, name);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.MultipleOf:
                if (EnsureVersion(SchemaVersion.Draft4))
                {
                    schema.MultipleOf = ReadDouble(reader, name);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.Disallow:
            {
                if (EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3))
                {
                    if (schema.Not == null)
                    {
                        schema.Not = new JSchema();
                    }

                    object disallowResult = ReadType(reader, name);
                    if (disallowResult is JSchemaType)
                    {
                        JSchemaType type = schema.Not.Type ?? JSchemaType.None;
                        schema.Not.Type = type | (JSchemaType)disallowResult;
                    }
                    else
                    {
                        schema.Not._anyOf = (List <JSchema>)disallowResult;
                    }
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;
            }

            case Constants.PropertyNames.Pattern:
                schema.Pattern = ReadString(reader, name);

                if (_validationErrors != null)
                {
                    Regex  patternRegex;
                    string errorMessage;
                    if (!schema.TryGetPatternRegex(out patternRegex, out errorMessage))
                    {
                        ValidationError error = ValidationError.CreateValidationError("Could not parse regex pattern '{0}'. Regex parser error: {1}".FormatWith(CultureInfo.InvariantCulture, schema.Pattern, errorMessage), ErrorType.Pattern, schema, null, schema.Pattern, null, schema, schema.Path);
                        _validationErrors.Add(error);
                    }
                }
                break;

            case Constants.PropertyNames.Enum:
                ReadTokenArray(reader, name, ref schema._enum);
                if (schema._enum.Count == 0)
                {
                    throw JSchemaReaderException.Create(reader, _baseUri, "Enum array must have at least one value.");
                }
                break;

            case Constants.PropertyNames.Extends:
                if (EnsureVersion(SchemaVersion.Draft3, SchemaVersion.Draft3))
                {
                    ReadExtends(reader, schema);
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;

            case Constants.PropertyNames.UniqueItems:
                schema.UniqueItems = ReadBoolean(reader, name);
                break;

            case Constants.PropertyNames.Default:
                EnsureRead(reader, Constants.PropertyNames.Default);
                schema.Default = JToken.ReadFrom(reader);
                break;

            default:
                if (isRoot && name == Constants.PropertyNames.Schema)
                {
                    if (!reader.Read())
                    {
                        throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected end when reading schema.");
                    }

                    if (reader.TokenType != JsonToken.String)
                    {
                        throw JSchemaReaderException.Create(reader, _baseUri, "Unexpected token encountered when reading value for '$schema'. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
                    }

                    _schemaVersionUri = new Uri((string)reader.Value, UriKind.RelativeOrAbsolute);

#if !PORTABLE
                    string tempUriText = _schemaVersionUri.OriginalString.ToLower(CultureInfo.InvariantCulture);
#else
                    string tempUriText = _schemaVersionUri.OriginalString.ToLower();
#endif

                    Uri tempUri = new Uri(tempUriText, UriKind.RelativeOrAbsolute);
                    if (tempUri == Constants.SchemaVersions.Draft3)
                    {
                        _schemaVersion = SchemaVersion.Draft3;
                    }
                    else if (tempUri == Constants.SchemaVersions.Draft4)
                    {
                        _schemaVersion = SchemaVersion.Draft4;
                    }

                    if (_validateSchema)
                    {
                        if (_schemaVersion == SchemaVersion.Draft3)
                        {
                            _validatingSchema = SpecSchemaCache.Get("schema-draft-v3.json");
                        }
                        else if (_schemaVersion == SchemaVersion.Draft4)
                        {
                            _validatingSchema = SpecSchemaCache.Get("schema-draft-v4.json");
                        }
                        else
                        {
                            if (!_schemaVersionUri.IsAbsoluteUri)
                            {
                                throw JSchemaReaderException.Create(reader, _baseUri, "Schema version identifier '{0}' is not an absolute URI.".FormatWith(CultureInfo.InvariantCulture, _schemaVersionUri.OriginalString));
                            }

                            _validatingSchema = ResolvedSchema(_schemaVersionUri, _schemaVersionUri);

                            if (_validatingSchema == null)
                            {
                                throw JSchemaReaderException.Create(reader, _baseUri, "Could not resolve schema version identifier '{0}'.".FormatWith(CultureInfo.InvariantCulture, _schemaVersionUri.OriginalString));
                            }
                        }

                        JSchemaValidatingReader validatingReader = new JSchemaValidatingReader(reader);
                        validatingReader.Schema = _validatingSchema;
                        // push state that we're already inside an object
                        validatingReader.Validator.ValidateCurrentToken(JsonToken.StartObject, null, 0);
                        validatingReader.ValidationEventHandler += RaiseSchemaValidationError;

                        reader = validatingReader;
                    }
                }
                else
                {
                    ReadExtensionData(reader, schema, name);
                }
                break;
            }
        }
        private void DiscoverInternal(JSchema schema, string latestPath)
        {
            if (schema.Reference != null)
            {
                return;
            }

            if (_knownSchemas.Contains(schema))
            {
                return;
            }

            Uri    newScopeId;
            string scopePath     = latestPath;
            Uri    schemaKnownId = GetSchemaIdAndNewScopeId(schema, ref scopePath, out newScopeId);

            // check whether a schema with the resolved id is already known
            // this will be hit when a schema contains duplicate ids or references a schema with a duplicate id
            bool existingSchema = _knownSchemas.GetById(schemaKnownId) != null;

#if DEBUG
            if (_knownSchemas.Contains(schema))
            {
                throw new InvalidOperationException("Schema with id '{0}' already a known schema.".FormatWith(CultureInfo.InvariantCulture, schemaKnownId));
            }
#endif

            // add schema to known schemas whether duplicate or not to avoid multiple errors
            // the first schema with a duplicate id will be used
            _knownSchemas.Add(new KnownSchema(schemaKnownId, schema, _state));

            if (existingSchema)
            {
                if (ValidationErrors != null)
                {
                    ValidationError error = ValidationError.CreateValidationError($"Duplicate schema id '{schemaKnownId.OriginalString}' encountered.", ErrorType.Id, schema, null, schemaKnownId, null, schema, schema.Path);
                    ValidationErrors.Add(error);
                }
            }

            _pathStack.Add(new SchemaPath(newScopeId, scopePath));

            // discover should happen in the same order as writer except extension data (e.g. definitions)
            if (schema._extensionData != null)
            {
                foreach (KeyValuePair <string, JToken> valuePair in schema._extensionData)
                {
                    DiscoverTokenSchemas(EscapePath(valuePair.Key), valuePair.Value);
                }
            }

            DiscoverSchema(Constants.PropertyNames.AdditionalProperties, schema.AdditionalProperties);
            DiscoverSchema(Constants.PropertyNames.AdditionalItems, schema.AdditionalItems);
            DiscoverDictionarySchemas(Constants.PropertyNames.Properties, schema._properties);
            DiscoverDictionarySchemas(Constants.PropertyNames.PatternProperties, schema._patternProperties);
            DiscoverDictionarySchemas(Constants.PropertyNames.Dependencies, schema._dependencies);
            if (schema.ItemsPositionValidation)
            {
                DiscoverArraySchemas(Constants.PropertyNames.Items, schema._items);
            }
            else if (schema._items != null && schema._items.Count > 0)
            {
                DiscoverSchema(Constants.PropertyNames.Items, schema._items[0]);
            }
            DiscoverArraySchemas(Constants.PropertyNames.AllOf, schema._allOf);
            DiscoverArraySchemas(Constants.PropertyNames.AnyOf, schema._anyOf);
            DiscoverArraySchemas(Constants.PropertyNames.OneOf, schema._oneOf);
            DiscoverSchema(Constants.PropertyNames.Not, schema.Not);

            _pathStack.RemoveAt(_pathStack.Count - 1);
        }
Beispiel #6
0
        private void DiscoverInternal(JSchema schema, string latestPath, bool isDefinitionSchema = false)
        {
            if (schema.Reference != null)
            {
                return;
            }

            // give schemas that are dependencies a special state so they are written as a dependency and not inline
            KnownSchemaState resolvedSchemaState = (_state == KnownSchemaState.InlinePending && isDefinitionSchema)
                ? KnownSchemaState.DefinitionPending
                : _state;

            string scopePath     = latestPath;
            Uri    schemaKnownId = GetSchemaIdAndNewScopeId(schema, ref scopePath, out Uri newScopeId);

            if (_knownSchemas.Contains(schema))
            {
                KnownSchema alreadyDiscoveredSchema = _knownSchemas[schema];

                // schema was previously discovered but exists in definitions
                if (alreadyDiscoveredSchema.State == KnownSchemaState.InlinePending &&
                    resolvedSchemaState == KnownSchemaState.DefinitionPending &&
                    _rootSchema != schema)
                {
                    int existingKnownSchemaIndex = _knownSchemas.IndexOf(alreadyDiscoveredSchema);

                    _knownSchemas[existingKnownSchemaIndex] = new KnownSchema(schemaKnownId, schema, resolvedSchemaState);
                }

                return;
            }

            // check whether a schema with the resolved id is already known
            // this will be hit when a schema contains duplicate ids or references a schema with a duplicate id
            bool existingSchema = _knownSchemas.GetById(schemaKnownId) != null;

            // add schema to known schemas whether duplicate or not to avoid multiple errors
            // the first schema with a duplicate id will be used
            _knownSchemas.Add(new KnownSchema(schemaKnownId, schema, resolvedSchemaState));

            if (existingSchema)
            {
                if (ValidationErrors != null)
                {
                    ValidationError error = ValidationError.CreateValidationError($"Duplicate schema id '{schemaKnownId.OriginalString}' encountered.", ErrorType.Id, schema, null, schemaKnownId, null, schema, schema.Path);
                    ValidationErrors.Add(error);
                }
            }

            _pathStack.Add(new SchemaPath(newScopeId, scopePath));

            // discover should happen in the same order as writer except extension data (e.g. definitions)
            if (schema._extensionData != null)
            {
                foreach (KeyValuePair <string, JToken> valuePair in schema._extensionData)
                {
                    DiscoverTokenSchemas(schema, EscapePath(valuePair.Key), valuePair.Value);
                }
            }

            DiscoverSchema(Constants.PropertyNames.AdditionalProperties, schema.AdditionalProperties);
            DiscoverSchema(Constants.PropertyNames.AdditionalItems, schema.AdditionalItems);
            DiscoverDictionarySchemas(Constants.PropertyNames.Properties, schema._properties);
            DiscoverDictionarySchemas(Constants.PropertyNames.PatternProperties, schema._patternProperties);
            DiscoverDictionarySchemas(Constants.PropertyNames.Dependencies, schema._dependencies);
            if (schema.ItemsPositionValidation)
            {
                DiscoverArraySchemas(Constants.PropertyNames.Items, schema._items);
            }
            else if (schema._items != null && schema._items.Count > 0)
            {
                DiscoverSchema(Constants.PropertyNames.Items, schema._items[0]);
            }
            DiscoverArraySchemas(Constants.PropertyNames.AllOf, schema._allOf);
            DiscoverArraySchemas(Constants.PropertyNames.AnyOf, schema._anyOf);
            DiscoverArraySchemas(Constants.PropertyNames.OneOf, schema._oneOf);
            DiscoverSchema(Constants.PropertyNames.Not, schema.Not);
            DiscoverSchema(Constants.PropertyNames.PropertyNamesSchema, schema.PropertyNames);
            DiscoverSchema(Constants.PropertyNames.Contains, schema.Contains);
            DiscoverSchema(Constants.PropertyNames.If, schema.If);
            DiscoverSchema(Constants.PropertyNames.Then, schema.Then);
            DiscoverSchema(Constants.PropertyNames.Else, schema.Else);

            _pathStack.RemoveAt(_pathStack.Count - 1);
        }