1# Detect BOM and possibly convert to UTF-8 and set UTF8 flag.
2#
3# https://tools.ietf.org/html/rfc7159#section-8.1
4# JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32.
5use Test::More ($] >= 5.008) ? (tests => 9) : (skip_all => "needs 5.8");;
6use Cpanel::JSON::XS;
7use Encode; # Currently required for <5.20
8use charnames qw(:short);
9use utf8;
10
11my $json = Cpanel::JSON::XS->new->utf8->allow_nonref;
12
13# parser need to succeed, result should be valid
14sub y_pass {
15  my ($str, $name) = @_;
16  my $result = $json->decode($str);
17  my $expected = ["é"];
18  is_deeply($result, $expected, "bom $name");
19}
20
21my @bom =
22  (
23   ["\xef\xbb\xbf[\"\303\251\"]",                       'UTF-8'],
24   ["\xfe\xff\000\133\000\042\000\351\000\042\000\135", 'UTF16-LE'],
25   ["\xff\xfe\133\000\042\000\351\000\042\000\135\000", 'UTF16-BE'],
26   ["\xff\xfe\000\000\133\000\000\000\042\000\000\000\351\000\000\000\042\000\000\000\135\000\000\000",   'UTF32-LE'],
27   ["\000\000\xfe\xff\000\000\000\133\000\000\000\042\000\000\000\351\000\000\000\042\000\000\000\135",   'UTF32-BE'],
28  );
29
30for my $bom (@bom) {
31  y_pass(@$bom);
32}
33
34# [GH #125] BOM in the middle corrupts state, sets utf8 flag
35my $j = Cpanel::JSON::XS->new;
36
37ok(my $as_json = eval {
38    $j->encode({ example => "data with non-ASCII characters",
39                 unicode => "\N{greek:Sigma}" })
40}, 'can encode a basic structure');
41ok(eval { $j->decode($as_json) }, 'can decode again');
42ok(eval { $j->decode("\x{feff}" . $as_json) }, 'can decode with BOM');
43ok(eval { $j->decode($as_json) }, 'can decode original');
44