Merge pull request #583 from ek08/fix

Checked the length of key for checker framework
This commit is contained in:
Sean Leary 2021-02-01 19:48:06 -06:00 committed by GitHub
commit 7844eb79cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -151,10 +151,10 @@ public class JSONObject {
return "null"; return "null";
} }
} }
/** /**
* Regular Expression Pattern that matches JSON Numbers. This is primarily used for * Regular Expression Pattern that matches JSON Numbers. This is primarily used for
* output to guarantee that we are always writing valid JSON. * output to guarantee that we are always writing valid JSON.
*/ */
static final Pattern NUMBER_PATTERN = Pattern.compile("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?"); static final Pattern NUMBER_PATTERN = Pattern.compile("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?");
@ -175,10 +175,10 @@ public class JSONObject {
* Construct an empty JSONObject. * Construct an empty JSONObject.
*/ */
public JSONObject() { public JSONObject() {
// HashMap is used on purpose to ensure that elements are unordered by // HashMap is used on purpose to ensure that elements are unordered by
// the specification. // the specification.
// JSON tends to be a portable transfer format to allows the container // JSON tends to be a portable transfer format to allows the container
// implementations to rearrange their items for a faster element // implementations to rearrange their items for a faster element
// retrieval based on associative access. // retrieval based on associative access.
// Therefore, an implementation mustn't rely on the order of the item. // Therefore, an implementation mustn't rely on the order of the item.
this.map = new HashMap<String, Object>(); this.map = new HashMap<String, Object>();
@ -239,9 +239,9 @@ public class JSONObject {
if (c != ':') { if (c != ':') {
throw x.syntaxError("Expected a ':' after a key"); throw x.syntaxError("Expected a ':' after a key");
} }
// Use syntaxError(..) to include error location // Use syntaxError(..) to include error location
if (key != null) { if (key != null) {
// Check if key exists // Check if key exists
if (this.opt(key) != null) { if (this.opt(key) != null) {
@ -350,11 +350,11 @@ public class JSONObject {
* method from being serialized: * method from being serialized:
* <pre> * <pre>
* &#64;JSONPropertyName("FullName") * &#64;JSONPropertyName("FullName")
* &#64;JSONPropertyIgnore * &#64;JSONPropertyIgnore
* public String getName() { return this.name; } * public String getName() { return this.name; }
* </pre> * </pre>
* <p> * <p>
* *
* @param bean * @param bean
* An object that has getter methods that should be used to make * An object that has getter methods that should be used to make
* a JSONObject. * a JSONObject.
@ -448,12 +448,12 @@ public class JSONObject {
} }
} }
} }
/** /**
* Constructor to specify an initial capacity of the internal map. Useful for library * Constructor to specify an initial capacity of the internal map. Useful for library
* internal calls where we know, or at least can best guess, how big this JSONObject * internal calls where we know, or at least can best guess, how big this JSONObject
* will be. * will be.
* *
* @param initialCapacity initial capacity of the internal map. * @param initialCapacity initial capacity of the internal map.
*/ */
protected JSONObject(int initialCapacity){ protected JSONObject(int initialCapacity){
@ -576,7 +576,7 @@ public class JSONObject {
/** /**
* Get the enum value associated with a key. * Get the enum value associated with a key.
* *
* @param <E> * @param <E>
* Enum Type * Enum Type
* @param clazz * @param clazz
@ -630,7 +630,7 @@ public class JSONObject {
* A key string. * A key string.
* @return The numeric value. * @return The numeric value.
* @throws JSONException * @throws JSONException
* if the key is not found or if the value cannot * if the key is not found or if the value cannot
* be converted to BigInteger. * be converted to BigInteger.
*/ */
public BigInteger getBigInteger(String key) throws JSONException { public BigInteger getBigInteger(String key) throws JSONException {
@ -929,7 +929,7 @@ public class JSONObject {
* modify the JSONObject. Use with caution. * modify the JSONObject. Use with caution.
* *
* @see Set#iterator() * @see Set#iterator()
* *
* @return An iterator of the keys. * @return An iterator of the keys.
*/ */
public Iterator<String> keys() { public Iterator<String> keys() {
@ -950,10 +950,10 @@ public class JSONObject {
/** /**
* Get a set of entries of the JSONObject. These are raw values and may not * Get a set of entries of the JSONObject. These are raw values and may not
* match what is returned by the JSONObject get* and opt* functions. Modifying * match what is returned by the JSONObject get* and opt* functions. Modifying
* the returned EntrySet or the Entry objects contained therein will modify the * the returned EntrySet or the Entry objects contained therein will modify the
* backing JSONObject. This does not return a clone or a read-only view. * backing JSONObject. This does not return a clone or a read-only view.
* *
* Use with caution. * Use with caution.
* *
* @see Map#entrySet() * @see Map#entrySet()
@ -1047,7 +1047,7 @@ public class JSONObject {
/** /**
* Get the enum value associated with a key. * Get the enum value associated with a key.
* *
* @param <E> * @param <E>
* Enum Type * Enum Type
* @param clazz * @param clazz
@ -1062,7 +1062,7 @@ public class JSONObject {
/** /**
* Get the enum value associated with a key. * Get the enum value associated with a key.
* *
* @param <E> * @param <E>
* Enum Type * Enum Type
* @param clazz * @param clazz
@ -1156,7 +1156,7 @@ public class JSONObject {
* @param val value to convert * @param val value to convert
* @param defaultValue default value to return is the conversion doesn't work or is null. * @param defaultValue default value to return is the conversion doesn't work or is null.
* @return BigDecimal conversion of the original value, or the defaultValue if unable * @return BigDecimal conversion of the original value, or the defaultValue if unable
* to convert. * to convert.
*/ */
static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) { static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) {
if (NULL.equals(val)) { if (NULL.equals(val)) {
@ -1206,7 +1206,7 @@ public class JSONObject {
* @param val value to convert * @param val value to convert
* @param defaultValue default value to return is the conversion doesn't work or is null. * @param defaultValue default value to return is the conversion doesn't work or is null.
* @return BigInteger conversion of the original value, or the defaultValue if unable * @return BigInteger conversion of the original value, or the defaultValue if unable
* to convert. * to convert.
*/ */
static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) { static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) {
if (NULL.equals(val)) { if (NULL.equals(val)) {
@ -1230,7 +1230,7 @@ public class JSONObject {
} }
// don't check if it's a string in case of unchecked Number subclasses // don't check if it's a string in case of unchecked Number subclasses
try { try {
// the other opt functions handle implicit conversions, i.e. // the other opt functions handle implicit conversions, i.e.
// jo.put("double",1.1d); // jo.put("double",1.1d);
// jo.optInt("double"); -- will return 1, not an error // jo.optInt("double"); -- will return 1, not an error
// this conversion to BigDecimal then to BigInteger is to maintain // this conversion to BigDecimal then to BigInteger is to maintain
@ -1404,10 +1404,10 @@ public class JSONObject {
if (val == null) { if (val == null) {
return defaultValue; return defaultValue;
} }
return val.longValue(); return val.longValue();
} }
/** /**
* Get an optional {@link Number} value associated with a key, or <code>null</code> * Get an optional {@link Number} value associated with a key, or <code>null</code>
* if there is no such key or if the value is not a number. If the value is a string, * if there is no such key or if the value is not a number. If the value is a string,
@ -1442,14 +1442,14 @@ public class JSONObject {
if (val instanceof Number){ if (val instanceof Number){
return (Number) val; return (Number) val;
} }
try { try {
return stringToNumber(val.toString()); return stringToNumber(val.toString());
} catch (Exception e) { } catch (Exception e) {
return defaultValue; return defaultValue;
} }
} }
/** /**
* Get an optional string associated with a key. It returns an empty string * Get an optional string associated with a key. It returns an empty string
* if there is no such key. If the value is not a string and is not null, * if there is no such key. If the value is not a string and is not null,
@ -1558,7 +1558,7 @@ public class JSONObject {
// if the first letter in the key is not uppercase, then skip. // if the first letter in the key is not uppercase, then skip.
// This is to maintain backwards compatibility before PR406 // This is to maintain backwards compatibility before PR406
// (https://github.com/stleary/JSON-java/pull/406/) // (https://github.com/stleary/JSON-java/pull/406/)
if (Character.isLowerCase(key.charAt(0))) { if (key.length() == 0 || Character.isLowerCase(key.charAt(0))) {
return null; return null;
} }
if (key.length() == 1) { if (key.length() == 1) {
@ -1735,7 +1735,7 @@ public class JSONObject {
public JSONObject put(String key, double value) throws JSONException { public JSONObject put(String key, double value) throws JSONException {
return this.put(key, Double.valueOf(value)); return this.put(key, Double.valueOf(value));
} }
/** /**
* Put a key/float pair in the JSONObject. * Put a key/float pair in the JSONObject.
* *
@ -1879,7 +1879,7 @@ public class JSONObject {
} }
/** /**
* Creates a JSONPointer using an initialization string and tries to * Creates a JSONPointer using an initialization string and tries to
* match it to an item within this JSONObject. For example, given a * match it to an item within this JSONObject. For example, given a
* JSONObject initialized with this document: * JSONObject initialized with this document:
* <pre> * <pre>
@ -1887,13 +1887,13 @@ public class JSONObject {
* "a":{"b":"c"} * "a":{"b":"c"}
* } * }
* </pre> * </pre>
* and this JSONPointer string: * and this JSONPointer string:
* <pre> * <pre>
* "/a/b" * "/a/b"
* </pre> * </pre>
* Then this method will return the String "c". * Then this method will return the String "c".
* A JSONPointerException may be thrown from code called by this method. * A JSONPointerException may be thrown from code called by this method.
* *
* @param jsonPointer string that can be used to create a JSONPointer * @param jsonPointer string that can be used to create a JSONPointer
* @return the item matched by the JSONPointer, otherwise null * @return the item matched by the JSONPointer, otherwise null
*/ */
@ -1901,7 +1901,7 @@ public class JSONObject {
return query(new JSONPointer(jsonPointer)); return query(new JSONPointer(jsonPointer));
} }
/** /**
* Uses a user initialized JSONPointer and tries to * Uses a user initialized JSONPointer and tries to
* match it to an item within this JSONObject. For example, given a * match it to an item within this JSONObject. For example, given a
* JSONObject initialized with this document: * JSONObject initialized with this document:
* <pre> * <pre>
@ -1909,24 +1909,24 @@ public class JSONObject {
* "a":{"b":"c"} * "a":{"b":"c"}
* } * }
* </pre> * </pre>
* and this JSONPointer: * and this JSONPointer:
* <pre> * <pre>
* "/a/b" * "/a/b"
* </pre> * </pre>
* Then this method will return the String "c". * Then this method will return the String "c".
* A JSONPointerException may be thrown from code called by this method. * A JSONPointerException may be thrown from code called by this method.
* *
* @param jsonPointer string that can be used to create a JSONPointer * @param jsonPointer string that can be used to create a JSONPointer
* @return the item matched by the JSONPointer, otherwise null * @return the item matched by the JSONPointer, otherwise null
*/ */
public Object query(JSONPointer jsonPointer) { public Object query(JSONPointer jsonPointer) {
return jsonPointer.queryFrom(this); return jsonPointer.queryFrom(this);
} }
/** /**
* Queries and returns a value from this object using {@code jsonPointer}, or * Queries and returns a value from this object using {@code jsonPointer}, or
* returns null if the query fails due to a missing key. * returns null if the query fails due to a missing key.
* *
* @param jsonPointer the string representation of the JSON pointer * @param jsonPointer the string representation of the JSON pointer
* @return the queried value or {@code null} * @return the queried value or {@code null}
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
@ -1934,11 +1934,11 @@ public class JSONObject {
public Object optQuery(String jsonPointer) { public Object optQuery(String jsonPointer) {
return optQuery(new JSONPointer(jsonPointer)); return optQuery(new JSONPointer(jsonPointer));
} }
/** /**
* Queries and returns a value from this object using {@code jsonPointer}, or * Queries and returns a value from this object using {@code jsonPointer}, or
* returns null if the query fails due to a missing key. * returns null if the query fails due to a missing key.
* *
* @param jsonPointer The JSON pointer * @param jsonPointer The JSON pointer
* @return the queried value or {@code null} * @return the queried value or {@code null}
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
@ -2090,18 +2090,18 @@ public class JSONObject {
return false; return false;
} }
} }
/** /**
* Compares two numbers to see if they are similar. * Compares two numbers to see if they are similar.
* *
* If either of the numbers are Double or Float instances, then they are checked to have * If either of the numbers are Double or Float instances, then they are checked to have
* a finite value. If either value is not finite (NaN or &#177;infinity), then this * a finite value. If either value is not finite (NaN or &#177;infinity), then this
* function will always return false. If both numbers are finite, they are first checked * function will always return false. If both numbers are finite, they are first checked
* to be the same type and implement {@link Comparable}. If they do, then the actual * to be the same type and implement {@link Comparable}. If they do, then the actual
* {@link Comparable#compareTo(Object)} is called. If they are not the same type, or don't * {@link Comparable#compareTo(Object)} is called. If they are not the same type, or don't
* implement Comparable, then they are converted to {@link BigDecimal}s. Finally the * implement Comparable, then they are converted to {@link BigDecimal}s. Finally the
* BigDecimal values are compared using {@link BigDecimal#compareTo(BigDecimal)}. * BigDecimal values are compared using {@link BigDecimal#compareTo(BigDecimal)}.
* *
* @param l the Left value to compare. Can not be <code>null</code>. * @param l the Left value to compare. Can not be <code>null</code>.
* @param r the right value to compare. Can not be <code>null</code>. * @param r the right value to compare. Can not be <code>null</code>.
* @return true if the numbers are similar, false otherwise. * @return true if the numbers are similar, false otherwise.
@ -2111,7 +2111,7 @@ public class JSONObject {
// non-finite numbers are never similar // non-finite numbers are never similar
return false; return false;
} }
// if the classes are the same and implement Comparable // if the classes are the same and implement Comparable
// then use the built in compare first. // then use the built in compare first.
if(l.getClass().equals(r.getClass()) && l instanceof Comparable) { if(l.getClass().equals(r.getClass()) && l instanceof Comparable) {
@ -2119,7 +2119,7 @@ public class JSONObject {
int compareTo = ((Comparable)l).compareTo(r); int compareTo = ((Comparable)l).compareTo(r);
return compareTo==0; return compareTo==0;
} }
// BigDecimal should be able to handle all of our number types that we support through // BigDecimal should be able to handle all of our number types that we support through
// documentation. Convert to BigDecimal first, then use the Compare method to // documentation. Convert to BigDecimal first, then use the Compare method to
// decide equality. // decide equality.
@ -2130,7 +2130,7 @@ public class JSONObject {
} }
return lBigDecimal.compareTo(rBigDecimal) == 0; return lBigDecimal.compareTo(rBigDecimal) == 0;
} }
private static boolean numberIsFinite(Number n) { private static boolean numberIsFinite(Number n) {
if (n instanceof Double && (((Double) n).isInfinite() || ((Double) n).isNaN())) { if (n instanceof Double && (((Double) n).isInfinite() || ((Double) n).isNaN())) {
return false; return false;
@ -2139,10 +2139,10 @@ public class JSONObject {
} }
return true; return true;
} }
/** /**
* Tests if the value should be tried as a decimal. It makes no test if there are actual digits. * Tests if the value should be tried as a decimal. It makes no test if there are actual digits.
* *
* @param val value to test * @param val value to test
* @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise. * @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise.
*/ */
@ -2150,12 +2150,12 @@ public class JSONObject {
return val.indexOf('.') > -1 || val.indexOf('e') > -1 return val.indexOf('.') > -1 || val.indexOf('e') > -1
|| val.indexOf('E') > -1 || "-0".equals(val); || val.indexOf('E') > -1 || "-0".equals(val);
} }
/** /**
* Converts a string to a number using the narrowest possible type. Possible * Converts a string to a number using the narrowest possible type. Possible
* returns for this function are BigDecimal, Double, BigInteger, Long, and Integer. * returns for this function are BigDecimal, Double, BigInteger, Long, and Integer.
* When a Double is returned, it should always be a valid Double and not NaN or +-infinity. * When a Double is returned, it should always be a valid Double and not NaN or +-infinity.
* *
* @param val value to convert * @param val value to convert
* @return Number representation of the value. * @return Number representation of the value.
* @throws NumberFormatException thrown if the value is not a valid number. A public * @throws NumberFormatException thrown if the value is not a valid number. A public
@ -2204,7 +2204,7 @@ public class JSONObject {
// integer representation. // integer representation.
// This will narrow any values to the smallest reasonable Object representation // This will narrow any values to the smallest reasonable Object representation
// (Integer, Long, or BigInteger) // (Integer, Long, or BigInteger)
// BigInteger down conversion: We use a similar bitLenth compare as // BigInteger down conversion: We use a similar bitLenth compare as
// BigInteger#intValueExact uses. Increases GC, but objects hold // BigInteger#intValueExact uses. Increases GC, but objects hold
// only what they need. i.e. Less runtime overhead if the value is // only what they need. i.e. Less runtime overhead if the value is
@ -2307,7 +2307,7 @@ public class JSONObject {
* <p><b> * <p><b>
* Warning: This method assumes that the data structure is acyclical. * Warning: This method assumes that the data structure is acyclical.
* </b> * </b>
* *
* @return a printable, displayable, portable, transmittable representation * @return a printable, displayable, portable, transmittable representation
* of the object, beginning with <code>{</code>&nbsp;<small>(left * of the object, beginning with <code>{</code>&nbsp;<small>(left
* brace)</small> and ending with <code>}</code>&nbsp;<small>(right * brace)</small> and ending with <code>}</code>&nbsp;<small>(right
@ -2324,11 +2324,11 @@ public class JSONObject {
/** /**
* Make a pretty-printed JSON text of this JSONObject. * Make a pretty-printed JSON text of this JSONObject.
* *
* <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject} * <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject}
* has only one key, then the object will be output on a single line: * has only one key, then the object will be output on a single line:
* <pre>{@code {"key": 1}}</pre> * <pre>{@code {"key": 1}}</pre>
* *
* <p>If an object has 2 or more keys, then it will be output across * <p>If an object has 2 or more keys, then it will be output across
* multiple lines: <pre>{@code { * multiple lines: <pre>{@code {
* "key1": 1, * "key1": 1,
@ -2506,11 +2506,11 @@ public class JSONObject {
/** /**
* Write the contents of the JSONObject as JSON text to a writer. * Write the contents of the JSONObject as JSON text to a writer.
* *
* <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject} * <p>If <pre>{@code indentFactor > 0}</pre> and the {@link JSONObject}
* has only one key, then the object will be output on a single line: * has only one key, then the object will be output on a single line:
* <pre>{@code {"key": 1}}</pre> * <pre>{@code {"key": 1}}</pre>
* *
* <p>If an object has 2 or more keys, then it will be output across * <p>If an object has 2 or more keys, then it will be output across
* multiple lines: <pre>{@code { * multiple lines: <pre>{@code {
* "key1": 1, * "key1": 1,
@ -2612,7 +2612,7 @@ public class JSONObject {
} }
return results; return results;
} }
/** /**
* Create a new JSONException in a common format for incorrect conversions. * Create a new JSONException in a common format for incorrect conversions.
* @param key name of the key * @param key name of the key
@ -2628,7 +2628,7 @@ public class JSONObject {
"JSONObject[" + quote(key) + "] is not a " + valueType + "." "JSONObject[" + quote(key) + "] is not a " + valueType + "."
, cause); , cause);
} }
/** /**
* Create a new JSONException in a common format for incorrect conversions. * Create a new JSONException in a common format for incorrect conversions.
* @param key name of the key * @param key name of the key