ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/CBOR-XS/XS.pm
(Generate patch)

Comparing CBOR-XS/XS.pm (file contents):
Revision 1.52 by root, Mon Apr 25 18:17:17 2016 UTC vs.
Revision 1.57 by root, Mon Apr 25 21:57:57 2016 UTC

64 64
65package CBOR::XS; 65package CBOR::XS;
66 66
67use common::sense; 67use common::sense;
68 68
69our $VERSION = 1.41; 69our $VERSION = 1.5;
70our @ISA = qw(Exporter); 70our @ISA = qw(Exporter);
71 71
72our @EXPORT = qw(encode_cbor decode_cbor); 72our @EXPORT = qw(encode_cbor decode_cbor);
73 73
74use Exporter; 74use Exporter;
588 my $x = 3.1; # some variable containing a number 588 my $x = 3.1; # some variable containing a number
589 "$x"; # stringified 589 "$x"; # stringified
590 $x .= ""; # another, more awkward way to stringify 590 $x .= ""; # another, more awkward way to stringify
591 print $x; # perl does it for you, too, quite often 591 print $x; # perl does it for you, too, quite often
592 592
593You can force whether a string ie encoded as byte or text string by using 593You can force whether a string is encoded as byte or text string by using
594C<utf8::upgrade> and C<utf8::downgrade>): 594C<utf8::upgrade> and C<utf8::downgrade> (if C<text_strings> is disabled):
595 595
596 utf8::upgrade $x; # encode $x as text string 596 utf8::upgrade $x; # encode $x as text string
597 utf8::downgrade $x; # encode $x as byte string 597 utf8::downgrade $x; # encode $x as byte string
598 598
599Perl doesn't define what operations up- and downgrade strings, so if the 599Perl doesn't define what operations up- and downgrade strings, so if the
600difference between byte and text is important, you should up- or downgrade 600difference between byte and text is important, you should up- or downgrade
601your string as late as possible before encoding. 601your string as late as possible before encoding. You can also force the
602use of CBOR text strings by using C<text_keys> or C<text_strings>.
602 603
603You can force the type to be a CBOR number by numifying it: 604You can force the type to be a CBOR number by numifying it:
604 605
605 my $x = "3"; # some variable containing a string 606 my $x = "3"; # some variable containing a string
606 $x += 0; # numify it, ensuring it will be dumped as a number 607 $x += 0; # numify it, ensuring it will be dumped as a number
926 927
927These tags are decoded into L<Math::BigInt> objects. The corresponding 928These tags are decoded into L<Math::BigInt> objects. The corresponding
928C<Math::BigInt::TO_CBOR> method encodes "small" bigints into normal CBOR 929C<Math::BigInt::TO_CBOR> method encodes "small" bigints into normal CBOR
929integers, and others into positive/negative CBOR bignums. 930integers, and others into positive/negative CBOR bignums.
930 931
931=item 4, 5 (decimal fraction/bigfloat) 932=item 4, 5, 264, 265 (decimal fraction/bigfloat)
932 933
933Both decimal fractions and bigfloats are decoded into L<Math::BigFloat> 934Both decimal fractions and bigfloats are decoded into L<Math::BigFloat>
934objects. The corresponding C<Math::BigFloat::TO_CBOR> method I<always> 935objects. The corresponding C<Math::BigFloat::TO_CBOR> method I<always>
935encodes into a decimal fraction. 936encodes into a decimal fraction (either tag 4 or 264).
936 937
937CBOR cannot represent bigfloats with I<very> large exponents - conversion 938NaN and infinities are not encoded properly, as they cannot be represented
938of such big float objects is undefined. 939in CBOR.
939 940
940Also, NaN and infinities are not encoded properly. 941See L<BIGNUM SECURITY CONSIDERATIONS> for more info.
941 942
942=item 21, 22, 23 (expected later JSON conversion) 943=item 21, 22, 23 (expected later JSON conversion)
943 944
944CBOR::XS is not a CBOR-to-JSON converter, and will simply ignore these 945CBOR::XS is not a CBOR-to-JSON converter, and will simply ignore these
945tags. 946tags.
1000 1001
1001Also keep in mind that CBOR::XS might leak contents of your Perl data 1002Also keep in mind that CBOR::XS might leak contents of your Perl data
1002structures in its error messages, so when you serialise sensitive 1003structures in its error messages, so when you serialise sensitive
1003information you might want to make sure that exceptions thrown by CBOR::XS 1004information you might want to make sure that exceptions thrown by CBOR::XS
1004will not end up in front of untrusted eyes. 1005will not end up in front of untrusted eyes.
1006
1007
1008=head1 BIGNUM SECURITY CONSIDERATIONS
1009
1010CBOR::XS provides a C<TO_CBOR> method for both L<Math::BigInt> and
1011L<Math::BigFloat> that tries to encode the number in the simplest possible
1012way, that is, either a CBOR integer, a CBOR bigint/decimal fraction (tag
10134) or an arbitrary-exponent decimal fraction (tag 264).
1014
1015It will also understand base-2 bigfloat or arbitrary-exponent bigfloats
1016(tags 5 and 265), but it will never generate these on its own.
1017
1018Using the built-in L<Math::BigInt::Calc> support, encoding and decoding
1019decimal fractions is generally fast. Decoding bigints can be slow for very
1020big numbers, and decoding bigfloats or arbitrary-exponent bigfloats can be
1021extremely slow (minutes, decades) for large exponents.
1022
1023Additionally, L<Math::BigInt> can take advantage of other bignum
1024libraries, such as L<Math::GMP>, which cannot handle big
1025floats with large exponents, and might simply abort or crash your program,
1026due to their code quality.
1027
1028This can be a concern if you want to parse untrusted CBOR. If it is, you
1029need to disable decoding of tag 2 (bigint) and 3 (negative bigint) types,
1030which will also disable bigfloat support (to be sure, you can also disable
1031types 4, 5, 264 and 265).
1032
1005 1033
1006=head1 CBOR IMPLEMENTATION NOTES 1034=head1 CBOR IMPLEMENTATION NOTES
1007 1035
1008This section contains some random implementation notes. They do not 1036This section contains some random implementation notes. They do not
1009describe guaranteed behaviour, but merely behaviour as-is implemented 1037describe guaranteed behaviour, but merely behaviour as-is implemented
1115 1143
1116 # 33 # base64url rfc4648, utf-8 1144 # 33 # base64url rfc4648, utf-8
1117 # 34 # base64 rfc46484, utf-8 1145 # 34 # base64 rfc46484, utf-8
1118 # 35 # regex pcre/ecma262, utf-8 1146 # 35 # regex pcre/ecma262, utf-8
1119 # 36 # mime message rfc2045, utf-8 1147 # 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 },
1120); 1158);
1121 1159
1122sub CBOR::XS::default_filter { 1160sub CBOR::XS::default_filter {
1123 &{ $FILTER{$_[0]} or return } 1161 &{ $FILTER{$_[0]} or return }
1124} 1162}
1128 utf8::upgrade $uri; 1166 utf8::upgrade $uri;
1129 tag 32, $uri 1167 tag 32, $uri
1130} 1168}
1131 1169
1132sub Math::BigInt::TO_CBOR { 1170sub Math::BigInt::TO_CBOR {
1133 if ($_[0] >= -2147483648 && $_[0] <= 2147483647) { 1171 if (-2147483648 <= $_[0] && $_[0] <= 2147483647) {
1134 $_[0]->numify 1172 $_[0]->numify
1135 } else { 1173 } else {
1136 my $hex = substr $_[0]->as_hex, 2; 1174 my $hex = substr $_[0]->as_hex, 2;
1137 $hex = "0$hex" if 1 & length $hex; # sigh 1175 $hex = "0$hex" if 1 & length $hex; # sigh
1138 tag $_[0] >= 0 ? 2 : 3, pack "H*", $hex 1176 tag $_[0] >= 0 ? 2 : 3, pack "H*", $hex
1139 } 1177 }
1140} 1178}
1141 1179
1142sub Math::BigFloat::TO_CBOR { 1180sub Math::BigFloat::TO_CBOR {
1143 my ($m, $e) = $_[0]->parts; 1181 my ($m, $e) = $_[0]->parts;
1182
1183 -9223372036854775808 <= $e && $e <= 18446744073709551615
1144 tag 4, [$e->numify, $m] 1184 ? tag 4, [$e->numify, $m]
1185 : tag 264, [$e, $m]
1145} 1186}
1146 1187
1147sub Time::Piece::TO_CBOR { 1188sub Time::Piece::TO_CBOR {
1148 tag 1, 0 + $_[0]->epoch 1189 tag 1, 0 + $_[0]->epoch
1149} 1190}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines