Repository: networknt/json-schema-validator
Pull request #90 (2018-07-30 11:18:54)

Remove unused dependency to slf4j-ext due to security issue
see for details:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-8088


Patch:
diff --git a/README.md b/README.md
index 0b27187..b44b006 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ Add the following to your `pom.xml`:
 <dependency>
     <groupId>com.networknt</groupId>
     <artifactId>json-schema-validator</artifactId>
-    <version>0.1.16</version>
+    <version>0.1.19</version>
 </dependency>
 ```
 
diff --git a/pom.xml b/pom.xml
index 42102c5..8bde3c7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,8 +13,8 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<project 
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+<project
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.networknt</groupId>
@@ -81,11 +81,6 @@
             <artifactId>slf4j-api</artifactId>
             <version>${version.slf4j}</version>
         </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-ext</artifactId>
-            <version>${version.slf4j}</version>
-        </dependency>
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
diff --git a/src/main/java/com/networknt/schema/BaseJsonValidator.java b/src/main/java/com/networknt/schema/BaseJsonValidator.java
index 0a6af8d..309ae43 100644
--- a/src/main/java/com/networknt/schema/BaseJsonValidator.java
+++ b/src/main/java/com/networknt/schema/BaseJsonValidator.java
@@ -53,7 +53,7 @@ public abstract class BaseJsonValidator implements JsonValidator {
         return schemaPath;
     }
 
-    protected JsonNode getSchemaNode() {
+    public JsonNode getSchemaNode() {
         return schemaNode;
     }
 
diff --git a/src/main/java/com/networknt/schema/CustomErrorMessageType.java b/src/main/java/com/networknt/schema/CustomErrorMessageType.java
index 4d8fe20..b29fa83 100644
--- a/src/main/java/com/networknt/schema/CustomErrorMessageType.java
+++ b/src/main/java/com/networknt/schema/CustomErrorMessageType.java
@@ -15,7 +15,7 @@ public class CustomErrorMessageType implements ErrorMessageType {
         return new CustomErrorMessageType(errorCode, null);
     }
     public static ErrorMessageType of(String errorCode, MessageFormat messageFormat) {
-        return new CustomErrorMessageType(errorCode, null);
+        return new CustomErrorMessageType(errorCode, messageFormat);
     }
 
     @Override
diff --git a/src/main/java/com/networknt/schema/TypeValidator.java b/src/main/java/com/networknt/schema/TypeValidator.java
index 781d24e..f370be9 100644
--- a/src/main/java/com/networknt/schema/TypeValidator.java
+++ b/src/main/java/com/networknt/schema/TypeValidator.java
@@ -49,12 +49,10 @@ public class TypeValidator extends BaseJsonValidator implements JsonValidator {
 
         JsonType nodeType = TypeFactory.getValueNodeType(node);
         if (nodeType != schemaType) {
-            if (schemaType == JsonType.ANY ) {
-                return Collections.emptySet();
-            }
-            if (schemaType == JsonType.NULL ) {
+            if (schemaType == JsonType.ANY) {
                 return Collections.emptySet();
             }
+
             if (schemaType == JsonType.NUMBER && nodeType == JsonType.INTEGER) {
                 return Collections.emptySet();
             }


Test patch:
diff --git a/src/test/java/com/networknt/schema/CustomMetaSchemaTest.java b/src/test/java/com/networknt/schema/CustomMetaSchemaTest.java
new file mode 100644
index 0000000..92bcafe
--- /dev/null
+++ b/src/test/java/com/networknt/schema/CustomMetaSchemaTest.java
@@ -0,0 +1,114 @@
+package com.networknt.schema;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class CustomMetaSchemaTest {
+
+    /**
+     * Introduces the keyword "enumNames".
+     * 
+     * The keyword is used together with "enum" and must have the same length.
+     * 
+     * This keyword always produces a warning during validation - 
+     * so it makes no sense in reality but should be useful for demonstration / testing purposes. 
+     * 
+     * @author klaskalass
+     *
+     */
+    public static class EnumNamesKeyword extends AbstractKeyword {
+
+        private static final class Validator extends AbstractJsonValidator {
+            private final List<String> enumValues;
+            private final List<String> enumNames;
+            
+            private Validator(String keyword, List<String> enumValues, List<String> enumNames) {
+                super(keyword);
+                if (enumNames.size() != enumValues.size()) {
+                    throw new IllegalArgumentException("enum and enumNames need to be of same length");
+                }
+                this.enumNames = enumNames;
+                this.enumValues = enumValues;
+            }
+
+            @Override
+            public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
+                String value = node.asText();
+                int idx = enumValues.indexOf(value);
+                if (idx < 0) {
+                    throw new IllegalArgumentException("value not found in enum. value: " + value  + " enum: " + enumValues);
+                }
+                String valueName = enumNames.get(idx);
+                return fail(CustomErrorMessageType.of("tests.example.enumNames", new MessageFormat("{0}: enumName is {1}")), at, valueName);
+            }
+        }
+
+        
+        public EnumNamesKeyword() {
+            super("enumNames");
+        }
+        
+        @Override
+        public JsonValidator newValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema,
+                ValidationContext validationContext) throws JsonSchemaException, Exception {
+            /*
+             * You can access the schema node here to read data from your keyword
+             */
+            if (!schemaNode.isArray()) {
+                throw new JsonSchemaException("Keyword enumNames needs to receive an array");
+            }
+            JsonNode parentSchemaNode = parentSchema.getSchemaNode();
+            if (!parentSchemaNode.has("enum")) {
+                throw new JsonSchemaException("Keyword enumNames needs to have a sibling enum keyword");
+            }
+            JsonNode enumSchemaNode = parentSchemaNode.get("enum");
+            
+            return new Validator(getValue(), readStringList(enumSchemaNode), readStringList(schemaNode));
+        }
+        
+        private List<String> readStringList(JsonNode node) {
+            if (!node.isArray()) {
+                throw new JsonSchemaException("Keyword enum needs to receive an array");
+            }
+            ArrayList<String> result = new ArrayList<>(node.size());
+            for (JsonNode child : node) {
+                result.add(child.asText());
+            }
+            return result;
+        }
+    }
+
+    @Test
+    public void customMetaSchemaWithIgnoredKeyword() throws JsonProcessingException, IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        final JsonMetaSchema metaSchema = JsonMetaSchema
+                .builder("https://github.com/networknt/json-schema-validator/tests/schemas/example01#", JsonMetaSchema.getDraftV4())
+                // Generated UI uses enumNames to render Labels for enum values
+                .addKeyword(new EnumNamesKeyword())
+                .build();
+        
+        final JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance()).addMetaSchema(metaSchema).build();
+        final JsonSchema schema = validatorFactory.getSchema("{\n" + 
+                "  \"$schema\":\n" + 
+                "    \"https://github.com/networknt/json-schema-validator/tests/schemas/example01#\",\n" + 
+                "  \"enum\": [\"foo\", \"bar\"],\n" + 
+                "  \"enumNames\": [\"Foo !\", \"Bar !\"]\n" + 
+                "}");
+        
+        Set<ValidationMessage> messages = schema.validate(objectMapper.readTree("\"foo\""));
+        assertEquals(1, messages.size());
+        
+        ValidationMessage message = messages.iterator().next();
+        assertEquals("$: enumName is Foo !", message.getMessage());
+    }
+}