… | |
… | |
64 | |
64 | |
65 | package CBOR::XS; |
65 | package CBOR::XS; |
66 | |
66 | |
67 | use common::sense; |
67 | use common::sense; |
68 | |
68 | |
69 | our $VERSION = 1.41; |
69 | our $VERSION = 1.51; |
70 | our @ISA = qw(Exporter); |
70 | our @ISA = qw(Exporter); |
71 | |
71 | |
72 | our @EXPORT = qw(encode_cbor decode_cbor); |
72 | our @EXPORT = qw(encode_cbor decode_cbor); |
73 | |
73 | |
74 | use Exporter; |
74 | use Exporter; |
… | |
… | |
180 | reference to the earlier value. |
180 | reference to the earlier value. |
181 | |
181 | |
182 | This means that such values will only be encoded once, and will not result |
182 | This means that such values will only be encoded once, and will not result |
183 | in a deep cloning of the value on decode, in decoders supporting the value |
183 | in a deep cloning of the value on decode, in decoders supporting the value |
184 | sharing extension. This also makes it possible to encode cyclic data |
184 | sharing extension. This also makes it possible to encode cyclic data |
185 | structures (which need C<allow_cycles> to ne enabled to be decoded by this |
185 | structures (which need C<allow_cycles> to be enabled to be decoded by this |
186 | module). |
186 | module). |
187 | |
187 | |
188 | It is recommended to leave it off unless you know your |
188 | It is recommended to leave it off unless you know your |
189 | communication partner supports the value sharing extensions to CBOR |
189 | communication partner supports the value sharing extensions to CBOR |
190 | (L<http://cbor.schmorp.de/value-sharing>), as without decoder support, the |
190 | (L<http://cbor.schmorp.de/value-sharing>), as without decoder support, the |
… | |
… | |
440 | |
440 | |
441 | Resets the incremental decoder. This throws away any saved state, so that |
441 | Resets the incremental decoder. This throws away any saved state, so that |
442 | subsequent calls to C<incr_parse> or C<incr_parse_multiple> start to parse |
442 | subsequent calls to C<incr_parse> or C<incr_parse_multiple> start to parse |
443 | a new CBOR value from the beginning of the C<$buffer> again. |
443 | a new CBOR value from the beginning of the C<$buffer> again. |
444 | |
444 | |
445 | This method can be caled at any time, but it I<must> be called if you want |
445 | This method can be called at any time, but it I<must> be called if you want |
446 | to change your C<$buffer> or there was a decoding error and you want to |
446 | to change your C<$buffer> or there was a decoding error and you want to |
447 | reuse the C<$cbor> object for future incremental parsings. |
447 | reuse the C<$cbor> object for future incremental parsings. |
448 | |
448 | |
449 | =back |
449 | =back |
450 | |
450 | |
… | |
… | |
927 | |
927 | |
928 | These tags are decoded into L<Math::BigInt> objects. The corresponding |
928 | These tags are decoded into L<Math::BigInt> objects. The corresponding |
929 | C<Math::BigInt::TO_CBOR> method encodes "small" bigints into normal CBOR |
929 | C<Math::BigInt::TO_CBOR> method encodes "small" bigints into normal CBOR |
930 | integers, and others into positive/negative CBOR bignums. |
930 | integers, and others into positive/negative CBOR bignums. |
931 | |
931 | |
932 | =item 4, 5 (decimal fraction/bigfloat) |
932 | =item 4, 5, 264, 265 (decimal fraction/bigfloat) |
933 | |
933 | |
934 | Both decimal fractions and bigfloats are decoded into L<Math::BigFloat> |
934 | Both decimal fractions and bigfloats are decoded into L<Math::BigFloat> |
935 | objects. The corresponding C<Math::BigFloat::TO_CBOR> method I<always> |
935 | objects. The corresponding C<Math::BigFloat::TO_CBOR> method I<always> |
936 | encodes into a decimal fraction. |
936 | encodes into a decimal fraction (either tag 4 or 264). |
937 | |
937 | |
938 | CBOR cannot represent bigfloats with I<very> large exponents - conversion |
938 | NaN and infinities are not encoded properly, as they cannot be represented |
939 | of such big float objects is undefined. |
939 | in CBOR. |
940 | |
940 | |
941 | Also, NaN and infinities are not encoded properly. |
941 | See L<BIGNUM SECURITY CONSIDERATIONS> for more info. |
|
|
942 | |
|
|
943 | =item 30 (rational numbers) |
|
|
944 | |
|
|
945 | These tags are decoded into L<Math::BigRat> objects. The corresponding |
|
|
946 | C<Math::BigRat::TO_CBOR> method encodes rational numbers with denominator |
|
|
947 | C<1> via their numerator only, i.e., they become normal integers or |
|
|
948 | C<bignums>. |
|
|
949 | |
|
|
950 | See L<BIGNUM SECURITY CONSIDERATIONS> for more info. |
942 | |
951 | |
943 | =item 21, 22, 23 (expected later JSON conversion) |
952 | =item 21, 22, 23 (expected later JSON conversion) |
944 | |
953 | |
945 | CBOR::XS is not a CBOR-to-JSON converter, and will simply ignore these |
954 | CBOR::XS is not a CBOR-to-JSON converter, and will simply ignore these |
946 | tags. |
955 | tags. |
… | |
… | |
1001 | |
1010 | |
1002 | Also keep in mind that CBOR::XS might leak contents of your Perl data |
1011 | Also keep in mind that CBOR::XS might leak contents of your Perl data |
1003 | structures in its error messages, so when you serialise sensitive |
1012 | structures in its error messages, so when you serialise sensitive |
1004 | information you might want to make sure that exceptions thrown by CBOR::XS |
1013 | information you might want to make sure that exceptions thrown by CBOR::XS |
1005 | will not end up in front of untrusted eyes. |
1014 | will not end up in front of untrusted eyes. |
|
|
1015 | |
|
|
1016 | |
|
|
1017 | =head1 BIGNUM SECURITY CONSIDERATIONS |
|
|
1018 | |
|
|
1019 | CBOR::XS provides a C<TO_CBOR> method for both L<Math::BigInt> and |
|
|
1020 | L<Math::BigFloat> that tries to encode the number in the simplest possible |
|
|
1021 | way, that is, either a CBOR integer, a CBOR bigint/decimal fraction (tag |
|
|
1022 | 4) or an arbitrary-exponent decimal fraction (tag 264). Rational numbers |
|
|
1023 | (L<Math::BigRat>, tag 30) can also contain bignums as members. |
|
|
1024 | |
|
|
1025 | CBOR::XS will also understand base-2 bigfloat or arbitrary-exponent |
|
|
1026 | bigfloats (tags 5 and 265), but it will never generate these on its own. |
|
|
1027 | |
|
|
1028 | Using the built-in L<Math::BigInt::Calc> support, encoding and decoding |
|
|
1029 | decimal fractions is generally fast. Decoding bigints can be slow for very |
|
|
1030 | big numbers (tens of thousands of digits, something that could potentially |
|
|
1031 | be caught by limiting the size of CBOR texts), and decoding bigfloats or |
|
|
1032 | arbitrary-exponent bigfloats can be I<extremely> slow (minutes, decades) |
|
|
1033 | for large exponents (roughly 40 bit and longer). |
|
|
1034 | |
|
|
1035 | Additionally, L<Math::BigInt> can take advantage of other bignum |
|
|
1036 | libraries, such as L<Math::GMP>, which cannot handle big floats with large |
|
|
1037 | exponents, and might simply abort or crash your program, due to their code |
|
|
1038 | quality. |
|
|
1039 | |
|
|
1040 | This can be a concern if you want to parse untrusted CBOR. If it is, you |
|
|
1041 | might want to disable decoding of tag 2 (bigint) and 3 (negative bigint) |
|
|
1042 | types. You should also disable types 5 and 265, as these can be slow even |
|
|
1043 | without bigints. |
|
|
1044 | |
|
|
1045 | Disabling bigints will also partially or fully disable types that rely on |
|
|
1046 | them, e.g. rational numbers that use bignums. |
|
|
1047 | |
1006 | |
1048 | |
1007 | =head1 CBOR IMPLEMENTATION NOTES |
1049 | =head1 CBOR IMPLEMENTATION NOTES |
1008 | |
1050 | |
1009 | This section contains some random implementation notes. They do not |
1051 | This section contains some random implementation notes. They do not |
1010 | describe guaranteed behaviour, but merely behaviour as-is implemented |
1052 | describe guaranteed behaviour, but merely behaviour as-is implemented |
… | |
… | |
1096 | 4 => sub { # decimal fraction, array |
1138 | 4 => sub { # decimal fraction, array |
1097 | require Math::BigFloat; |
1139 | require Math::BigFloat; |
1098 | Math::BigFloat->new ($_[1][1] . "E" . $_[1][0]) |
1140 | Math::BigFloat->new ($_[1][1] . "E" . $_[1][0]) |
1099 | }, |
1141 | }, |
1100 | |
1142 | |
|
|
1143 | 264 => sub { # decimal fraction with arbitrary exponent |
|
|
1144 | require Math::BigFloat; |
|
|
1145 | Math::BigFloat->new ($_[1][1] . "E" . $_[1][0]) |
|
|
1146 | }, |
|
|
1147 | |
1101 | 5 => sub { # bigfloat, array |
1148 | 5 => sub { # bigfloat, array |
1102 | require Math::BigFloat; |
1149 | require Math::BigFloat; |
1103 | scalar Math::BigFloat->new ($_[1][1]) * Math::BigFloat->new (2)->bpow ($_[1][0]) |
1150 | scalar Math::BigFloat->new ($_[1][1]) * Math::BigFloat->new (2)->bpow ($_[1][0]) |
|
|
1151 | }, |
|
|
1152 | |
|
|
1153 | 265 => sub { # bigfloat with arbitrary exponent |
|
|
1154 | require Math::BigFloat; |
|
|
1155 | scalar Math::BigFloat->new ($_[1][1]) * Math::BigFloat->new (2)->bpow ($_[1][0]) |
|
|
1156 | }, |
|
|
1157 | |
|
|
1158 | 30 => sub { # rational number |
|
|
1159 | require Math::BigRat; |
|
|
1160 | Math::BigRat->new ("$_[1][0]/$_[1][1]") # separate parameters only work in recent versons |
1104 | }, |
1161 | }, |
1105 | |
1162 | |
1106 | 21 => sub { pop }, # expected conversion to base64url encoding |
1163 | 21 => sub { pop }, # expected conversion to base64url encoding |
1107 | 22 => sub { pop }, # expected conversion to base64 encoding |
1164 | 22 => sub { pop }, # expected conversion to base64 encoding |
1108 | 23 => sub { pop }, # expected conversion to base16 encoding |
1165 | 23 => sub { pop }, # expected conversion to base16 encoding |
… | |
… | |
1129 | utf8::upgrade $uri; |
1186 | utf8::upgrade $uri; |
1130 | tag 32, $uri |
1187 | tag 32, $uri |
1131 | } |
1188 | } |
1132 | |
1189 | |
1133 | sub Math::BigInt::TO_CBOR { |
1190 | sub Math::BigInt::TO_CBOR { |
1134 | if ($_[0] >= -2147483648 && $_[0] <= 2147483647) { |
1191 | if (-2147483648 <= $_[0] && $_[0] <= 2147483647) { |
1135 | $_[0]->numify |
1192 | $_[0]->numify |
1136 | } else { |
1193 | } else { |
1137 | my $hex = substr $_[0]->as_hex, 2; |
1194 | my $hex = substr $_[0]->as_hex, 2; |
1138 | $hex = "0$hex" if 1 & length $hex; # sigh |
1195 | $hex = "0$hex" if 1 & length $hex; # sigh |
1139 | tag $_[0] >= 0 ? 2 : 3, pack "H*", $hex |
1196 | tag $_[0] >= 0 ? 2 : 3, pack "H*", $hex |
1140 | } |
1197 | } |
1141 | } |
1198 | } |
1142 | |
1199 | |
1143 | sub Math::BigFloat::TO_CBOR { |
1200 | sub Math::BigFloat::TO_CBOR { |
1144 | my ($m, $e) = $_[0]->parts; |
1201 | my ($m, $e) = $_[0]->parts; |
|
|
1202 | |
|
|
1203 | -9223372036854775808 <= $e && $e <= 18446744073709551615 |
1145 | tag 4, [$e->numify, $m] |
1204 | ? tag 4, [$e->numify, $m] |
|
|
1205 | : tag 264, [$e, $m] |
|
|
1206 | } |
|
|
1207 | |
|
|
1208 | sub Math::BigRat::TO_CBOR { |
|
|
1209 | my ($n, $d) = $_[0]->parts; |
|
|
1210 | |
|
|
1211 | # older versions of BigRat need *1, as they not always return numbers |
|
|
1212 | |
|
|
1213 | $d*1 == 1 |
|
|
1214 | ? $n*1 |
|
|
1215 | : tag 30, [$n*1, $d*1] |
1146 | } |
1216 | } |
1147 | |
1217 | |
1148 | sub Time::Piece::TO_CBOR { |
1218 | sub Time::Piece::TO_CBOR { |
1149 | tag 1, 0 + $_[0]->epoch |
1219 | tag 1, 0 + $_[0]->epoch |
1150 | } |
1220 | } |