[JAVA-2478] org.bson.types.StringRangeSet.contains() throws NumberFormatException when input is not number Created: 25/Mar/17  Updated: 04/Apr/17  Resolved: 04/Apr/17

Status: Closed
Project: Java Driver
Component/s: BSON
Affects Version/s: 3.0.0
Fix Version/s: 3.5.0

Type: Bug Priority: Minor - P4
Reporter: Yonatan Graber Assignee: Jeffrey Yemin
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

When the DBObject.keySet() rerturns a Set<String> that is an instance of StringRangeSet, performing keySet.contains("FOO") on it will throw NumberFormatException.
Caused due to the contains implementation that assume input is a valid number:

 @Override
    public boolean contains(final Object o) {
        if (!(o instanceof String)) {
            return false;
        }
        int i = Integer.parseInt((String) o);
        return i >= 0 && i < size();
    }

Using a non-number contains can be a valid use case when recursively iterating through a DBObject, trying to remove all "_class" fields that spring-data-mongo generate:

private void removeClassFields(DBObject dbObject){
        Set<String> keys = dbObject.keySet();
        if (keys.contains("_class")){
            dbObject.removeField("_class");
        }
        for (String key : keys) {
            if (dbObject.get(key) instanceof DBObject){
                removeClassFields((DBObject) dbObject.get(key));
            }
        }
    }



 Comments   
Comment by Githook User [ 04/Apr/17 ]

Author:

{u'username': u'jyemin', u'name': u'Jeff Yemin', u'email': u'jeff.yemin@10gen.com'}

Message: JAVA-2478: Change StringRangeSet.contains to properly return false instead of throwing NumberFormatException when the parameter is a string that can't be parsed as an int
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/08208b9ddf2aafcea0dc3da4c2f024defee83bfd

Comment by Jeffrey Yemin [ 26/Mar/17 ]

A simple workaround is to add a check to ensure the DBObject is a BSON document and not a BSON array:

        if (!(doc instanceof List)) {            // ensure doc is not an array before checking keys
            if (keys.contains("_class")) {
                doc.removeField("_class");
            }
        }

Generated at Thu Feb 08 08:57:19 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.