basex failed to cast large numbers as xs:integer

Thursday, 22 February 2024 · 2 messages
MZ
mx z22 Feb 2024 20:22 #

Hi, I found a bug in basex. Version: 1ce0618 (2024.02.22)

Java: openjdk 17.0.9 2023-10-17 LTS OpenJDK Runtime Environment Corretto-17.0.9.8.1 (build 17.0.9+8-LTS) OpenJDK 64-Bit Server VM Corretto-17.0.9.8.1 (build 17.0.9+8-LTS, mixed mode, sharing)

OS: Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy

input.xml:

<a xmlns:C="p">
        <C:A id="1">1458820431</C:A>1438466813
</a>

query.xq: //*[not(. castable as xs:integer)]

Reproduce: java -cp basex-core/target/basex-11.0-SNAPSHOT.jar org.basex.BaseX -i input.xml query.xq

It printed out
<a xmlns:C="p">
        <C:A id="1">1458820431</C:A>1438466813
</a>

While basex should return empty, as both 1458820431 and 1438466813 are integers.

Max Zhang

CG
Christian Grün22 Feb 2024 20:36 #

Hi Max,

Thanks for your report.

The behavior is correct, but I agree it’s surprising:

• //* returns two results: <a.../> and <C:A.../> • the atomized value of <a.../> is '14588204311438466813'. This value exceeds the BaseX limit for integers (2^64), which is why [not(. castable as xs:integer)] returns true for this element. • the atomized value of <C:A.../> is 1458820431. This value can be represented as xs:integer, so – as expected – [not(. castable as xs:integer)] reurns false.

If you want to want to check for numbers that exceed the 2^64 limit, you can use xs:decimal tests. If you want to check if the single text nodes are integers, you can use:

//text()[not(. castable as xs:integer)]

Hope this helps, Christian


⚡Generated with XQuery