diff options
author | Karl Williamson <public@khwilliamson.com> | 2011-11-09 15:54:55 -0700 |
---|---|---|
committer | Karl Williamson <public@khwilliamson.com> | 2011-11-09 16:24:05 -0700 |
commit | 84ea5ef60b4892d6c262690549b1bd78970108e4 (patch) | |
tree | c3475d690a2ec9b8c1c31846decd67d25d0245b0 | |
parent | 45d91b83242e04182e545e492a98ea94c6f0b3d6 (diff) | |
download | perl-84ea5ef60b4892d6c262690549b1bd78970108e4.tar.gz |
utf8.c: Make swashes work close to UV_MAX
When a code point is to be checked if it matches a property, a swatch of
the swash is read in. Typically this is a block of 64 code points that
contain the one desired. A bit map is set for those 64 code points,
apparently under the expectation that the program will desire code
points near the original.
However, it just adds 63 to the original code point to get the ending
point of the block. When the original is so close to the maximum UV
expressible on the platform, this will overflow.
The patch is simply to check for overflow and if it happens use the max
possible. A special case is still needed to handle the very maximum
possible code point, and a future commit will deal with that.
-rw-r--r-- | t/re/pat_advanced.t | 11 | ||||
-rw-r--r-- | utf8.c | 8 |
2 files changed, 15 insertions, 4 deletions
diff --git a/t/re/pat_advanced.t b/t/re/pat_advanced.t index e4a6851425..e0db844c87 100644 --- a/t/re/pat_advanced.t +++ b/t/re/pat_advanced.t @@ -2125,9 +2125,14 @@ EOP # We use 'ok' instead of 'like' because the warnings are lexically # scoped, and want to turn them off, so have to do the match in this # scope - if ($Config{uvsize} >= 8) { - ok(chr(0xFFFF_FFFF_FFFF) =~ qr/\p{Is_Super}/, - "chr(0xFFFF_FFFF_FFFF) can match a Unicode property"); + if ($Config{uvsize} < 8) { + ok(chr(0xFFFF_FFFE) =~ /\p{Is_Super}/, + "chr(0xFFFF_FFFE) can match a Unicode property"); + } + else { + no warnings 'overflow'; + ok(chr(0xFFFF_FFFF_FFFF_FFFE) =~ qr/\p{Is_Super}/, + "chr(0xFFFF_FFFF_FFFF_FFFE) can match a Unicode property"); } } @@ -2580,7 +2580,7 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) const STRLEN bits = SvUV(*bitssvp); const STRLEN octets = bits >> 3; /* if bits == 1, then octets == 0 */ const UV none = SvUV(*nonesvp); - const UV end = start + span; + UV end = start + span; PERL_ARGS_ASSERT_SWASH_GET; @@ -2589,6 +2589,12 @@ S_swash_get(pTHX_ SV* swash, UV start, UV span) (UV)bits); } + /* If overflowed, use the max possible */ + if (end < start) { + end = UV_MAX; + span = end - start; + } + /* create and initialize $swatch */ scur = octets ? (span * octets) : (span + 7) / 8; swatch = newSV(scur); |