diff options
author | HÃ¥kon Hallingstad <hakon@verizonmedia.com> | 2020-04-15 17:03:26 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-15 17:03:26 +0200 |
commit | 1eecdac6160ea9f7ed6de5e3fc478bc211561dc2 (patch) | |
tree | 5e9fc0a7b6735521c3d47d4ce9b4ee1a113b23e7 /vespajlib/src/main/java | |
parent | 7c1004ffb82e0512278826d24edf9dbdc91186e1 (diff) | |
parent | 4422d42987bb9aefa92abd4cb4135798479edb6a (diff) |
Merge pull request #12882 from vespa-engine/hakonhall/validate-deserialization-of-flag-data
Validate deserialization of flag data
Diffstat (limited to 'vespajlib/src/main/java')
5 files changed, 66 insertions, 6 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/slime/JsonDecoder.java b/vespajlib/src/main/java/com/yahoo/slime/JsonDecoder.java index f199fefd185..f677ae23a45 100644 --- a/vespajlib/src/main/java/com/yahoo/slime/JsonDecoder.java +++ b/vespajlib/src/main/java/com/yahoo/slime/JsonDecoder.java @@ -3,10 +3,8 @@ package com.yahoo.slime; import com.yahoo.text.Text; import com.yahoo.text.Utf8; -import org.w3c.dom.CharacterData; import java.io.ByteArrayOutputStream; -import java.nio.charset.StandardCharsets; /** * A port of the C++ json decoder intended to be fast. @@ -47,6 +45,17 @@ public class JsonDecoder { return slime; } + /** Decode bytes as a UTF-8 JSON into Slime, or throw {@link JsonParseException} on invalid JSON. */ + public Slime decodeOrThrow(Slime slime, byte[] bytes) { + in = new BufferedInput(bytes); + next(); + decodeValue(slimeInserter.adjust(slime)); + if (in.failed()) { + throw new JsonParseException(in); + } + return slime; + } + private void decodeValue(Inserter inserter) { skipWhiteSpace(); switch (c) { diff --git a/vespajlib/src/main/java/com/yahoo/slime/JsonParseException.java b/vespajlib/src/main/java/com/yahoo/slime/JsonParseException.java new file mode 100644 index 00000000000..6c42f7d38c1 --- /dev/null +++ b/vespajlib/src/main/java/com/yahoo/slime/JsonParseException.java @@ -0,0 +1,23 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.slime; + +/** + * @author hakonhall + */ +public class JsonParseException extends RuntimeException { + + private static final long serialVersionUID = 1586949558L; + + private final BufferedInput input; + + JsonParseException(BufferedInput input) { + super(input.getErrorMessage()); + this.input = input; + } + + public byte[] getOffendingBytes() { + // potentially expensive array copy + return input.getOffending(); + } + +} diff --git a/vespajlib/src/main/java/com/yahoo/slime/Slime.java b/vespajlib/src/main/java/com/yahoo/slime/Slime.java index 8357e3035c0..83934e0c206 100644 --- a/vespajlib/src/main/java/com/yahoo/slime/Slime.java +++ b/vespajlib/src/main/java/com/yahoo/slime/Slime.java @@ -159,11 +159,10 @@ public final class Slime { } /** - * Tests whether this is equal to Inspector. + * Tests whether the two Inspectors are equal. * - * Since equality of two Inspectors is subtle, {@link Object#equals(Object)} is not used. + * <p>Since equality of two Inspectors is subtle, {@link Object#equals(Object)} is not used.</p> * - * @param that inspector. * @return true if they are equal. */ public boolean equalTo(Slime that) { diff --git a/vespajlib/src/main/java/com/yahoo/slime/SlimeUtils.java b/vespajlib/src/main/java/com/yahoo/slime/SlimeUtils.java index 4d0b3a8ff2e..2ed7331a60c 100644 --- a/vespajlib/src/main/java/com/yahoo/slime/SlimeUtils.java +++ b/vespajlib/src/main/java/com/yahoo/slime/SlimeUtils.java @@ -104,6 +104,17 @@ public class SlimeUtils { return jsonToSlime(json.getBytes(StandardCharsets.UTF_8)); } + /** Throws {@link JsonParseException} on invalid JSON. */ + public static Slime jsonToSlimeOrThrow(String json) { + return jsonToSlimeOrThrow(json.getBytes(StandardCharsets.UTF_8)); + } + + public static Slime jsonToSlimeOrThrow(byte[] json) { + Slime slime = new Slime(); + new JsonDecoder().decodeOrThrow(slime, json); + return slime; + } + public static Optional<String> optionalString(Inspector inspector) { return Optional.of(inspector.asString()).filter(s -> !s.isEmpty()); } diff --git a/vespajlib/src/main/java/com/yahoo/text/JSON.java b/vespajlib/src/main/java/com/yahoo/text/JSON.java index cfff16c9aba..11e5be9328e 100644 --- a/vespajlib/src/main/java/com/yahoo/text/JSON.java +++ b/vespajlib/src/main/java/com/yahoo/text/JSON.java @@ -1,10 +1,13 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.text; +import com.yahoo.slime.Slime; +import com.yahoo.slime.SlimeUtils; + import java.util.Map; /** - * Static methods for working with the map textual format which is parsed by {@link MapParser} + * Static methods for working with JSON. * * @author bratseth */ @@ -56,4 +59,19 @@ public final class JSON { return b != null ? b.toString() : s; } + /** + * Test whether two JSON strings are equal, e.g. the order of fields in an object is irrelevant. + * + * <p>When comparing two numbers of the two JSON strings, the result is only guaranteed to be + * correct if (a) both are integers (without fraction and exponent) and each fits in a long, or + * (b) both are non-integers, are syntactically identical, and fits in a double.</p> + * + * @throws RuntimeException on invalid JSON + */ + public static boolean equals(String left, String right) { + Slime leftSlime = SlimeUtils.jsonToSlimeOrThrow(left); + Slime rightSlime = SlimeUtils.jsonToSlimeOrThrow(right); + return leftSlime.equalTo(rightSlime); + } + } |