… | |
… | |
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 (either tag 4 or 264). |
936 | encodes into a decimal fraction (either tag 4 or 264). |
937 | |
937 | |
938 | NaN and infinities are not encoded properly, as they cannot be represented |
938 | NaN and infinities are not encoded properly, as they cannot be represented |
939 | in CBOR. |
939 | in CBOR. |
|
|
940 | |
|
|
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>. |
940 | |
949 | |
941 | See L<BIGNUM SECURITY CONSIDERATIONS> for more info. |
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 | |
… | |
… | |
1008 | =head1 BIGNUM SECURITY CONSIDERATIONS |
1017 | =head1 BIGNUM SECURITY CONSIDERATIONS |
1009 | |
1018 | |
1010 | CBOR::XS provides a C<TO_CBOR> method for both L<Math::BigInt> and |
1019 | CBOR::XS provides a C<TO_CBOR> method for both L<Math::BigInt> and |
1011 | L<Math::BigFloat> that tries to encode the number in the simplest possible |
1020 | L<Math::BigFloat> that tries to encode the number in the simplest possible |
1012 | way, that is, either a CBOR integer, a CBOR bigint/decimal fraction (tag |
1021 | way, that is, either a CBOR integer, a CBOR bigint/decimal fraction (tag |
1013 | 4) or an arbitrary-exponent decimal fraction (tag 264). |
1022 | 4) or an arbitrary-exponent decimal fraction (tag 264). Rational numbers |
|
|
1023 | (L<Math::BigRat>, tag 30) can also contain bignums as members. |
1014 | |
1024 | |
1015 | It will also understand base-2 bigfloat or arbitrary-exponent bigfloats |
1025 | CBOR::XS will also understand base-2 bigfloat or arbitrary-exponent |
1016 | (tags 5 and 265), but it will never generate these on its own. |
1026 | bigfloats (tags 5 and 265), but it will never generate these on its own. |
1017 | |
1027 | |
1018 | Using the built-in L<Math::BigInt::Calc> support, encoding and decoding |
1028 | Using the built-in L<Math::BigInt::Calc> support, encoding and decoding |
1019 | decimal fractions is generally fast. Decoding bigints can be slow for very |
1029 | decimal fractions is generally fast. Decoding bigints can be slow for very |
1020 | big numbers, and decoding bigfloats or arbitrary-exponent bigfloats can be |
1030 | big numbers (tens of thousands of digits, something that could potentially |
1021 | extremely slow (minutes, decades) for large exponents. |
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). |
1022 | |
1034 | |
1023 | Additionally, L<Math::BigInt> can take advantage of other bignum |
1035 | Additionally, L<Math::BigInt> can take advantage of other bignum |
1024 | libraries, such as L<Math::GMP>, which cannot handle big |
1036 | libraries, such as L<Math::GMP>, which cannot handle big floats with large |
1025 | floats with large exponents, and might simply abort or crash your program, |
1037 | exponents, and might simply abort or crash your program, due to their code |
1026 | due to their code quality. |
1038 | quality. |
1027 | |
1039 | |
1028 | This can be a concern if you want to parse untrusted CBOR. If it is, you |
1040 | This can be a concern if you want to parse untrusted CBOR. If it is, you |
1029 | need to disable decoding of tag 2 (bigint) and 3 (negative bigint) types, |
1041 | might want to disable decoding of tag 2 (bigint) and 3 (negative bigint) |
1030 | which will also disable bigfloat support (to be sure, you can also disable |
1042 | types. You should also disable types 5 and 265, as these can be slow even |
1031 | types 4, 5, 264 and 265). |
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. |
1032 | |
1047 | |
1033 | |
1048 | |
1034 | =head1 CBOR IMPLEMENTATION NOTES |
1049 | =head1 CBOR IMPLEMENTATION NOTES |
1035 | |
1050 | |
1036 | This section contains some random implementation notes. They do not |
1051 | This section contains some random implementation notes. They do not |
… | |
… | |
1110 | scalar Time::Piece::gmtime (pop) |
1125 | scalar Time::Piece::gmtime (pop) |
1111 | }, |
1126 | }, |
1112 | |
1127 | |
1113 | 2 => sub { # pos bigint |
1128 | 2 => sub { # pos bigint |
1114 | require Math::BigInt; |
1129 | require Math::BigInt; |
1115 | Math::BigInt->from_hex ("0x" . unpack "H*", pop) |
1130 | Math::BigInt->new ("0x" . unpack "H*", pop) |
1116 | }, |
1131 | }, |
1117 | |
1132 | |
1118 | 3 => sub { # neg bigint |
1133 | 3 => sub { # neg bigint |
1119 | require Math::BigInt; |
1134 | require Math::BigInt; |
1120 | -Math::BigInt->from_hex ("0x" . unpack "H*", pop) |
1135 | -Math::BigInt->new ("0x" . unpack "H*", pop) |
1121 | }, |
1136 | }, |
1122 | |
1137 | |
1123 | 4 => sub { # decimal fraction, array |
1138 | 4 => sub { # decimal fraction, array |
1124 | require Math::BigFloat; |
1139 | require Math::BigFloat; |
1125 | Math::BigFloat->new ($_[1][1] . "E" . $_[1][0]) |
1140 | Math::BigFloat->new ($_[1][1] . "E" . $_[1][0]) |
1126 | }, |
1141 | }, |
1127 | |
1142 | |
|
|
1143 | 264 => sub { # decimal fraction with arbitrary exponent |
|
|
1144 | require Math::BigFloat; |
|
|
1145 | Math::BigFloat->new ($_[1][1] . "E" . $_[1][0]) |
|
|
1146 | }, |
|
|
1147 | |
1128 | 5 => sub { # bigfloat, array |
1148 | 5 => sub { # bigfloat, array |
1129 | require Math::BigFloat; |
1149 | require Math::BigFloat; |
1130 | 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]) |
1131 | }, |
1151 | }, |
1132 | |
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 |
|
|
1161 | }, |
|
|
1162 | |
1133 | 21 => sub { pop }, # expected conversion to base64url encoding |
1163 | 21 => sub { pop }, # expected conversion to base64url encoding |
1134 | 22 => sub { pop }, # expected conversion to base64 encoding |
1164 | 22 => sub { pop }, # expected conversion to base64 encoding |
1135 | 23 => sub { pop }, # expected conversion to base16 encoding |
1165 | 23 => sub { pop }, # expected conversion to base16 encoding |
1136 | |
1166 | |
1137 | # 24 # embedded cbor, byte string |
1167 | # 24 # embedded cbor, byte string |
… | |
… | |
1143 | |
1173 | |
1144 | # 33 # base64url rfc4648, utf-8 |
1174 | # 33 # base64url rfc4648, utf-8 |
1145 | # 34 # base64 rfc46484, utf-8 |
1175 | # 34 # base64 rfc46484, utf-8 |
1146 | # 35 # regex pcre/ecma262, utf-8 |
1176 | # 35 # regex pcre/ecma262, utf-8 |
1147 | # 36 # mime message rfc2045, utf-8 |
1177 | # 36 # mime message rfc2045, utf-8 |
1148 | |
|
|
1149 | 264 => sub { # decimal fraction with arbitrary exponent |
|
|
1150 | require Math::BigFloat; |
|
|
1151 | Math::BigFloat->new ($_[1][1] . "E" . $_[1][0]) |
|
|
1152 | }, |
|
|
1153 | |
|
|
1154 | 265 => sub { # bigfloat with arbitrary exponent |
|
|
1155 | require Math::BigFloat; |
|
|
1156 | scalar Math::BigFloat->new ($_[1][1]) * Math::BigFloat->new (2)->bpow ($_[1][0]) |
|
|
1157 | }, |
|
|
1158 | ); |
1178 | ); |
1159 | |
1179 | |
1160 | sub CBOR::XS::default_filter { |
1180 | sub CBOR::XS::default_filter { |
1161 | &{ $FILTER{$_[0]} or return } |
1181 | &{ $FILTER{$_[0]} or return } |
1162 | } |
1182 | } |
… | |
… | |
1183 | -9223372036854775808 <= $e && $e <= 18446744073709551615 |
1203 | -9223372036854775808 <= $e && $e <= 18446744073709551615 |
1184 | ? tag 4, [$e->numify, $m] |
1204 | ? tag 4, [$e->numify, $m] |
1185 | : tag 264, [$e, $m] |
1205 | : tag 264, [$e, $m] |
1186 | } |
1206 | } |
1187 | |
1207 | |
|
|
1208 | sub Math::BigRat::TO_CBOR { |
|
|
1209 | my ($n, $d) = $_[0]->parts; |
|
|
1210 | |
|
|
1211 | $d == 1 |
|
|
1212 | ? $n |
|
|
1213 | : tag 30, [$n, $d] |
|
|
1214 | } |
|
|
1215 | |
1188 | sub Time::Piece::TO_CBOR { |
1216 | sub Time::Piece::TO_CBOR { |
1189 | tag 1, 0 + $_[0]->epoch |
1217 | tag 1, 0 + $_[0]->epoch |
1190 | } |
1218 | } |
1191 | |
1219 | |
1192 | XSLoader::load "CBOR::XS", $VERSION; |
1220 | XSLoader::load "CBOR::XS", $VERSION; |