owlcs / owlapi

OWL API main repository
813 stars 314 forks source link

Uncaught NumberFormatException when comparing (large) integers #1126

Open gouttegd opened 4 months ago

gouttegd commented 4 months ago

This issue was initially reported on the Protégé bug tracker.

Protégé encounters an uncaught NumberFormatException in the OWL API when trying to display the http://www.semanticweb.org/ReproduceError/Testing/SuperClass1#subclass class from the ontology in the attached file: ReproduceErrorNumberFormatException2.txt

This is because of the large integer value 92740100783 in one of the class expressions defining the class.

In code, the easiest way to reproduce the bug is (assuming df is an OWLDataFactory):

OWLLiteral smallInteger = df.getOWLLiteral(123);
OWLLiteral largeInteger = df.getOWLLiteral("92740100783", df.getIntegerOWLDatatype());
smallInteger.compareTo(largeInteger);

The compareTo call raises a NumberFormatException. I believe the issues lies in the equals(OWLObject) method of the OWLLiteralImplInteger class:

public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (!super.equals(obj)) {
        return false;
    }
    if (obj instanceof OWLLiteralImplInteger) {
        OWLLiteralImplInteger other = (OWLLiteralImplInteger) obj;
        return literal == other.literal;
    }
    if (obj instanceof OWLLiteral) {
        return ((OWLLiteral) obj).isInteger()
            && ((OWLLiteral) obj).getLiteral().charAt(0) != '0'
            && literal == ((OWLLiteral) obj).parseInteger();
    }
    return false;
}

because the call to parseInteger() is not protected. If obj happens to be an instance of OWLLiteralImplNoCompression containing the string representation of a large integer, that call will raise the NumberFormatException.

ignazio1977 commented 4 months ago

Looks like there's also some funny business in the literal parsing, as the value for owl:hasValue does not have a specified datatype and so shouldn't have been parsed to an integer literal.