From 31ff8a229129d8450da236633aac8d320aba87ff Mon Sep 17 00:00:00 2001 From: Ehtesham Date: Wed, 27 Jan 2021 11:35:38 +0530 Subject: [PATCH 1/2] Checked the length of key for checker framework --- src/main/java/org/json/JSONObject.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index b60344bad..8517feb18 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -1558,7 +1558,7 @@ private static String getKeyNameFromMethod(Method method) { // if the first letter in the key is not uppercase, then skip. // This is to maintain backwards compatibility before PR406 // (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; } if (key.length() == 1) { From 5b531faa49f7f8247511d7ea74043932de19e327 Mon Sep 17 00:00:00 2001 From: Ehtesham Date: Thu, 28 Jan 2021 15:31:23 +0530 Subject: [PATCH 2/2] Improved the logic for checking the length of key --- src/main/java/org/json/JSONObject.java | 116 ++++++++++++------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index 8517feb18..8bbb874b3 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -151,10 +151,10 @@ public String toString() { return "null"; } } - + /** * 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+)?"); @@ -175,10 +175,10 @@ public String toString() { * Construct an empty 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. - // JSON tends to be a portable transfer format to allows the container - // implementations to rearrange their items for a faster element + // JSON tends to be a portable transfer format to allows the container + // implementations to rearrange their items for a faster element // retrieval based on associative access. // Therefore, an implementation mustn't rely on the order of the item. this.map = new HashMap(); @@ -239,9 +239,9 @@ public JSONObject(JSONTokener x) throws JSONException { if (c != ':') { throw x.syntaxError("Expected a ':' after a key"); } - + // Use syntaxError(..) to include error location - + if (key != null) { // Check if key exists if (this.opt(key) != null) { @@ -350,11 +350,11 @@ public JSONObject(Map m) { * method from being serialized: *
      * @JSONPropertyName("FullName")
-     * @JSONPropertyIgnore 
+     * @JSONPropertyIgnore
      * public String getName() { return this.name; }
      * 
*

- * + * * @param bean * An object that has getter methods that should be used to make * a JSONObject. @@ -448,12 +448,12 @@ public JSONObject(String baseName, Locale locale) throws JSONException { } } } - + /** - * 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 * will be. - * + * * @param initialCapacity initial capacity of the internal map. */ protected JSONObject(int initialCapacity){ @@ -576,7 +576,7 @@ public Object get(String key) throws JSONException { /** * Get the enum value associated with a key. - * + * * @param * Enum Type * @param clazz @@ -630,7 +630,7 @@ public boolean getBoolean(String key) throws JSONException { * A key string. * @return The numeric value. * @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. */ public BigInteger getBigInteger(String key) throws JSONException { @@ -929,7 +929,7 @@ public boolean isNull(String key) { * modify the JSONObject. Use with caution. * * @see Set#iterator() - * + * * @return An iterator of the keys. */ public Iterator keys() { @@ -950,10 +950,10 @@ public Set keySet() { /** * 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 * backing JSONObject. This does not return a clone or a read-only view. - * + * * Use with caution. * * @see Map#entrySet() @@ -1047,7 +1047,7 @@ public Object opt(String key) { /** * Get the enum value associated with a key. - * + * * @param * Enum Type * @param clazz @@ -1062,7 +1062,7 @@ public > E optEnum(Class clazz, String key) { /** * Get the enum value associated with a key. - * + * * @param * Enum Type * @param clazz @@ -1156,7 +1156,7 @@ public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) { * @param val value to convert * @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 - * to convert. + * to convert. */ static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) { if (NULL.equals(val)) { @@ -1206,7 +1206,7 @@ public BigInteger optBigInteger(String key, BigInteger defaultValue) { * @param val value to convert * @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 - * to convert. + * to convert. */ static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) { if (NULL.equals(val)) { @@ -1230,7 +1230,7 @@ static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) { } // don't check if it's a string in case of unchecked Number subclasses 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.optInt("double"); -- will return 1, not an error // this conversion to BigDecimal then to BigInteger is to maintain @@ -1404,10 +1404,10 @@ public long optLong(String key, long defaultValue) { if (val == null) { return defaultValue; } - + return val.longValue(); } - + /** * Get an optional {@link Number} value associated with a key, or null * 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 Number optNumber(String key, Number defaultValue) { if (val instanceof Number){ return (Number) val; } - + try { return stringToNumber(val.toString()); } catch (Exception e) { return defaultValue; } } - + /** * 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, @@ -1558,7 +1558,7 @@ private static String getKeyNameFromMethod(Method method) { // if the first letter in the key is not uppercase, then skip. // This is to maintain backwards compatibility before PR406 // (https://github.com/stleary/JSON-java/pull/406/) - if (key.length() > 0 && Character.isLowerCase(key.charAt(0))) { + if (key.length() == 0 || Character.isLowerCase(key.charAt(0))) { return null; } if (key.length() == 1) { @@ -1735,7 +1735,7 @@ public JSONObject put(String key, Collection value) throws JSONException { public JSONObject put(String key, double value) throws JSONException { return this.put(key, Double.valueOf(value)); } - + /** * Put a key/float pair in the JSONObject. * @@ -1879,7 +1879,7 @@ public JSONObject putOpt(String key, Object value) throws JSONException { } /** - * 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 * JSONObject initialized with this document: *

@@ -1887,13 +1887,13 @@ public JSONObject putOpt(String key, Object value) throws JSONException {
      *     "a":{"b":"c"}
      * }
      * 
- * and this JSONPointer string: + * and this JSONPointer string: *
      * "/a/b"
      * 
* Then this method will return the String "c". * A JSONPointerException may be thrown from code called by this method. - * + * * @param jsonPointer string that can be used to create a JSONPointer * @return the item matched by the JSONPointer, otherwise null */ @@ -1901,7 +1901,7 @@ public Object query(String 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 * JSONObject initialized with this document: *
@@ -1909,24 +1909,24 @@ public Object query(String jsonPointer) {
      *     "a":{"b":"c"}
      * }
      * 
- * and this JSONPointer: + * and this JSONPointer: *
      * "/a/b"
      * 
* Then this method will return the String "c". * A JSONPointerException may be thrown from code called by this method. - * + * * @param jsonPointer string that can be used to create a JSONPointer * @return the item matched by the JSONPointer, otherwise null */ public Object query(JSONPointer jsonPointer) { return jsonPointer.queryFrom(this); } - + /** * Queries and returns a value from this object using {@code jsonPointer}, or * returns null if the query fails due to a missing key. - * + * * @param jsonPointer the string representation of the JSON pointer * @return the queried value or {@code null} * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax @@ -1934,11 +1934,11 @@ public Object query(JSONPointer jsonPointer) { public Object optQuery(String jsonPointer) { return optQuery(new JSONPointer(jsonPointer)); } - + /** * Queries and returns a value from this object using {@code jsonPointer}, or * returns null if the query fails due to a missing key. - * + * * @param jsonPointer The JSON pointer * @return the queried value or {@code null} * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax @@ -2090,18 +2090,18 @@ public boolean similar(Object other) { return false; } } - + /** * 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 * a finite value. If either value is not finite (NaN or ±infinity), then this * 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 * {@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)}. - * + * * @param l the Left value to compare. Can not be null. * @param r the right value to compare. Can not be null. * @return true if the numbers are similar, false otherwise. @@ -2111,7 +2111,7 @@ static boolean isNumberSimilar(Number l, Number r) { // non-finite numbers are never similar return false; } - + // if the classes are the same and implement Comparable // then use the built in compare first. if(l.getClass().equals(r.getClass()) && l instanceof Comparable) { @@ -2119,7 +2119,7 @@ static boolean isNumberSimilar(Number l, Number r) { int compareTo = ((Comparable)l).compareTo(r); return compareTo==0; } - + // 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 // decide equality. @@ -2130,7 +2130,7 @@ static boolean isNumberSimilar(Number l, Number r) { } return lBigDecimal.compareTo(rBigDecimal) == 0; } - + private static boolean numberIsFinite(Number n) { if (n instanceof Double && (((Double) n).isInfinite() || ((Double) n).isNaN())) { return false; @@ -2139,10 +2139,10 @@ private static boolean numberIsFinite(Number n) { } return true; } - + /** * Tests if the value should be tried as a decimal. It makes no test if there are actual digits. - * + * * @param val value to test * @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise. */ @@ -2150,12 +2150,12 @@ protected static boolean isDecimalNotation(final String val) { return val.indexOf('.') > -1 || val.indexOf('e') > -1 || 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. * When a Double is returned, it should always be a valid Double and not NaN or +-infinity. - * + * * @param val value to convert * @return Number representation of the value. * @throws NumberFormatException thrown if the value is not a valid number. A public @@ -2204,7 +2204,7 @@ protected static Number stringToNumber(final String val) throws NumberFormatExce // integer representation. // This will narrow any values to the smallest reasonable Object representation // (Integer, Long, or BigInteger) - + // BigInteger down conversion: We use a similar bitLenth compare as // BigInteger#intValueExact uses. Increases GC, but objects hold // only what they need. i.e. Less runtime overhead if the value is @@ -2307,7 +2307,7 @@ public JSONArray toJSONArray(JSONArray names) throws JSONException { *

* Warning: This method assumes that the data structure is acyclical. * - * + * * @return a printable, displayable, portable, transmittable representation * of the object, beginning with { (left * brace) and ending with } (right @@ -2324,11 +2324,11 @@ public String toString() { /** * Make a pretty-printed JSON text of this JSONObject. - * + * *

If

{@code indentFactor > 0}
and the {@link JSONObject} * has only one key, then the object will be output on a single line: *
{@code {"key": 1}}
- * + * *

If an object has 2 or more keys, then it will be output across * multiple lines:

{@code {
      *  "key1": 1,
@@ -2506,11 +2506,11 @@ static final void indent(Writer writer, int indent) throws IOException {
 
     /**
      * Write the contents of the JSONObject as JSON text to a writer.
-     * 
+     *
      * 

If

{@code indentFactor > 0}
and the {@link JSONObject} * has only one key, then the object will be output on a single line: *
{@code {"key": 1}}
- * + * *

If an object has 2 or more keys, then it will be output across * multiple lines:

{@code {
      *  "key1": 1,
@@ -2612,7 +2612,7 @@ public Map toMap() {
         }
         return results;
     }
-    
+
     /**
      * Create a new JSONException in a common format for incorrect conversions.
      * @param key name of the key
@@ -2628,7 +2628,7 @@ private static JSONException wrongValueFormatException(
                 "JSONObject[" + quote(key) + "] is not a " + valueType + "."
                 , cause);
     }
-    
+
     /**
      * Create a new JSONException in a common format for incorrect conversions.
      * @param key name of the key