Skip to content

Commit 9760391

Browse files
G4Virurban
authored andcommitted
Error on lone surrogates
1 parent 146af14 commit 9760391

4 files changed

Lines changed: 48 additions & 7 deletions

File tree

‎README‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,16 @@ A FEW NOTES ON UNICODE AND PERL
293293
Unicode RFC 7159 section 8.1. We use now the UTF8_DISALLOW_SUPER
294294
flag when parsing unicode.
295295

296+
8. Lone surrogates or illegal surrogate pairs are disallowed.
297+
Since RFC 3629, U+D800 through U+DFFF are not legal Unicode values
298+
and their UTF-8 encodings must be treated as an invalid byte
299+
sequence. RFC 8259 section 8.2 admits the spec allows string values
300+
that contain bit sequences that cannot encode Unicode characters and
301+
that the behavior of software that recieves such values is
302+
unpredictable. To avoid introducing non-Unicode strings into Perl we
303+
use the UTF8_DISALLOW_SURROGATE flag when parsing Unicode and verify
304+
escaped surrogates form valid pairs.
305+
296306
I hope this helps :)
297307

298308
OBJECT-ORIENTED INTERFACE
@@ -1809,6 +1819,15 @@ ENCODING/CODESET FLAG NOTES
18091819
Unicode RFC 7159 section 8.1. We use now the UTF8_DISALLOW_SUPER flag
18101820
when parsing unicode.
18111821

1822+
Since RFC 3629, U+D800 through U+DFFF are not legal Unicode values and
1823+
their UTF-8 encodings must be treated as an invalid byte sequence. RFC
1824+
8259 section 8.2 admits the spec allows string values that contain bit
1825+
sequences that cannot encode Unicode characters and that the behavior of
1826+
software that recieves such values is unpredictable. To avoid
1827+
introducing non-Unicode strings into Perl we use the
1828+
UTF8_DISALLOW_SURROGATE flag when parsing Unicode and verify escaped
1829+
surrogates form valid pairs.
1830+
18121831
If you know of other incompatibilities, please let me know.
18131832

18141833
JSON and YAML

‎XS.pm‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,17 @@ characters" RFC 7159 section 1 and "JSON text SHALL be encoded in
362362
Unicode RFC 7159 section 8.1. We use now the UTF8_DISALLOW_SUPER
363363
flag when parsing unicode.
364364
365+
=item 8. Lone surrogates or illegal surrogate pairs are disallowed.
366+
367+
Since RFC 3629, U+D800 through U+DFFF are not legal Unicode values and
368+
their UTF-8 encodings must be treated as an invalid byte sequence.
369+
RFC 8259 section 8.2 admits the spec allows string values that contain
370+
bit sequences that cannot encode Unicode characters and that the
371+
behavior of software that recieves such values is unpredictable. To
372+
avoid introducing non-Unicode strings into Perl we use the
373+
UTF8_DISALLOW_SURROGATE flag when parsing Unicode and verify escaped
374+
surrogates form valid pairs.
375+
365376
=back
366377
367378
I hope this helps :)
@@ -1997,6 +2008,15 @@ characters" RFC 7159 section 1 and "JSON text SHALL be encoded in
19972008
Unicode RFC 7159 section 8.1. We use now the UTF8_DISALLOW_SUPER
19982009
flag when parsing unicode.
19992010
2011+
Since RFC 3629, U+D800 through U+DFFF are not legal Unicode values and
2012+
their UTF-8 encodings must be treated as an invalid byte sequence.
2013+
RFC 8259 section 8.2 admits the spec allows string values that contain
2014+
bit sequences that cannot encode Unicode characters and that the
2015+
behavior of software that recieves such values is unpredictable. To
2016+
avoid introducing non-Unicode strings into Perl we use the
2017+
UTF8_DISALLOW_SURROGATE flag when parsing Unicode and verify escaped
2018+
surrogates form valid pairs.
2019+
20002020
If you know of other incompatibilities, please let me know.
20012021
20022022

‎XS.xs‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -551,17 +551,19 @@ decode_utf8 (pTHX_ unsigned char *s, STRLEN len, int relaxed, STRLEN *clen)
551551
return ((s[0] & 0x1f) << 6) | (s[1] & 0x3f);
552552
}
553553
else {
554-
/* Since perl 5.14 we can disallow illegal unicode above U+10FFFF.
554+
/* Since perl 5.14 we can disallow surrogates and illegal unicode above
555+
U+10FFFF.
555556
Before we could only warn with warnings 'utf8'.
556-
We accept only valid unicode, unless we are in the relaxed mode,
557-
which allows SUPER, above U+10FFFF.
557+
Surrogates are never allowed for consistency with unpaired escaped surrogate
558+
handling.
559+
SUPER, above U+10FFFF is not allowed, unless we are in the relaxed mode.
558560
*/
559561
#if PERL_VERSION > 36
560562
UV c = utf8n_to_uvchr (s, len, clen,
561-
UTF8_CHECK_ONLY | (relaxed ? 0 : UTF8_DISALLOW_SUPER));
563+
UTF8_CHECK_ONLY | UTF8_DISALLOW_SURROGATE | (relaxed ? 0 : UTF8_DISALLOW_SUPER));
562564
#elif PERL_VERSION > 12
563565
UV c = utf8n_to_uvuni (s, len, clen,
564-
UTF8_CHECK_ONLY | (relaxed ? 0 : UTF8_DISALLOW_SUPER));
566+
UTF8_CHECK_ONLY | UTF8_DISALLOW_SURROGATE | (relaxed ? 0 : UTF8_DISALLOW_SUPER));
565567
#elif PERL_VERSION >= 8
566568
UV c = utf8n_to_uvuni (s, len, clen, UTF8_CHECK_ONLY);
567569
#endif

‎t/30_jsonspec.t‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ my $json = Cpanel::JSON::XS->new->utf8->allow_nonref;
99
my $relaxed = Cpanel::JSON::XS->new->utf8->allow_nonref->relaxed;
1010

1111
# fixme:
12-
# n_string_UTF8_surrogate_U+D800 ["EDA080"] <=> [""] unicode
1312
# done:
1413
# i_string_unicode_*_nonchar ["\uDBFF\uDFFE"] (add warning as in core)
1514
# i_string_not_in_unicode_range Code point 0x13FFFF is not Unicode UTF8_DISALLOW_SUPER
1615
# y_string_utf16, y_string_utf16be, y_string_utf32, y_string_utf32be fixed with 3.0222
16+
# n_string_UTF8_surrogate_U+D800 Code point 0xD800 is not Unicode UTF8_DISALLOW_SURROGATE
1717
my %todo;
18+
$todo{'n_string_UTF8_surrogate_U+D800'}++ if $] < 5.014;
1819
$todo{'y_string_nonCharacterInUTF-8_U+FFFF'}++ if $] < 5.013;
19-
$todo{'n_string_UTF8_surrogate_U+D800'}++ if $] >= 5.012;
2020
if ($] < 5.008) {
2121
# 5.6 has no multibyte support
2222
$todo{$_}++ for qw(

0 commit comments

Comments
 (0)