summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Williamson <public@khwilliamson.com>2011-11-09 15:54:55 -0700
committerKarl Williamson <public@khwilliamson.com>2011-11-09 16:24:05 -0700
commit84ea5ef60b4892d6c262690549b1bd78970108e4 (patch)
treec3475d690a2ec9b8c1c31846decd67d25d0245b0
parent45d91b83242e04182e545e492a98ea94c6f0b3d6 (diff)
downloadperl-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.t11
-rw-r--r--utf8.c8
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");
}
}
diff --git a/utf8.c b/utf8.c
index 9c55d10c25..5ff9ccb3b1 100644
--- a/utf8.c
+++ b/utf8.c
@@ -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);