peteroupc / CBOR-Java

A Java implementation of Concise Binary Object Representation (RFC 8949)
The Unlicense
42 stars 10 forks source link

CBORNumber.IsNumber() is classifying many numbers as 'not number' #18

Closed EskoDijk closed 1 year ago

EskoDijk commented 3 years ago

Hello, one issue I found with CBORNumber.IsNumber() , is that it classifies many number elements as 'not number' (false). This happens if the number in the element, e.g. a CBOR unsigned integer, is tagged.

I see in the IANA assignments that in some cases 'non-number CBOR elements' , i.e. elements not integers and not floats, can be interpreted as numbers if these are prefixed with a particular tag like 30, 264, 265, 268, 269, 270 and 2,3,4,5. These are special cases that the method can test for (and does test for).

However in the common case a tagged unsigned integer, signed integer or float should be classified as 'number' (so: true). Because

For information, my particular case was using an integer that is tagged with 47 ; a SID - which is a number for sure. Here IsNumber() gives 'false'.

So by default I would give any tagged uint/int/float object which isn't an array the benefit of the doubt and classify them as number. Only those tags that explicitly remove the "numberness" of a uint/int/float object would need to be included in the code as special cases and for those the method should return 'false'. It could be that the IANA registry contains such cases, but again I haven't seen these so far! I would be interested to learn if there are cases like these. Thanks :)

peteroupc commented 3 years ago

Thank you for your comment. In the meantime, you can also do cbor.Untag().IsNumber() to determine whether a CBOR object stores a number (or cbor.Type == CBORType.Integer || cbor.Type==CBORType.FloatingPoint). You can also write a custom extension method that classifies CBOR objects in the manner you care about.

EskoDijk commented 3 years ago

Thanks, yes I was already using the Untag() for this purpose.

peteroupc commented 1 year ago

This issue has seen no activity, and it appears to be resolved, so closing.

mjviljan commented 2 months ago

Hi, and first of all, thanks for the great library!

I ran into this same issue now, although with a different tag. In my case I have a CBOR object that has a base time value wrapped in the tag 1, and it isn't recognized as a number.

A minimal example:

[{-3: 1(1720696276)}]

I can't say if EskoDijk's suggestion above – interpreting all tagged numbers as numbers by default – would be feasible, but e.g. in this case of mine, tag 1 is defined in RFC 8949 as "Epoch-Based Date/Time", with the following explanation:

Tag number 1 contains a numerical value counting the number of seconds from 1970-01-01T00:00Z in UTC time to the represented point in civil time.

(I also realize the project is aimed to implement RFC 7049, and not RFC 8949 which was only published in December 2020. But the old one defined the tag pretty similarly.)

Untagging the value surely works in this case also, but unfortunately I use CBOR-Java as a dependency of another library, Eclipse Leshan, so I'm not in direct control of its usage. I've opened an issue there to discuss if this should be fixed there, and if so, how.

Any thoughts on this? If it would make sense to change this, I can provide a PR.

peteroupc commented 2 months ago

The README still says RFC 7049; I meant to update that to say RFC 8949 instead. The Untag() approach will work fine as long as you have verified the correct tag.