This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
PATCH: [perl #133896] Assertion failure
authorKarl Williamson <khw@cpan.org>
Fri, 5 Apr 2019 22:21:51 +0000 (16:21 -0600)
committerKarl Williamson <khw@cpan.org>
Fri, 5 Apr 2019 23:14:11 +0000 (17:14 -0600)
This was due to UTF8_SAFE_SKIP(s, e) not allowing s to be as large as e,
and there are legitimate cases where it can be.  This commit hardens the
macro so that it never reads above e-1, returning 0 if it otherwise
would be required to.  The assertion is changed to 's <= e'.

t/re/reg_mesg.t
utf8.h

index 9939646..4a652ba 100644 (file)
@@ -316,6 +316,7 @@ my @death =
  '/[^/' => 'Unmatched [ {#} m/[{#}^/', # [perl #133767]
  '/\p{Is_Other_Alphabetic=F}/ ' => 'Can\'t find Unicode property definition "Is_Other_Alphabetic=F" {#} m/\p{Is_Other_Alphabetic=F}{#}/',
  '/\p{Is_Other_Alphabetic=F}/ ' => 'Can\'t find Unicode property definition "Is_Other_Alphabetic=F" {#} m/\p{Is_Other_Alphabetic=F}{#}/',
+ '/\x{100}(?(/' => 'Unknown switch condition (?(...)) {#} m/\\x{100}(?({#}/', # [perl #133896]
 );
 
 # These are messages that are death under 'use re "strict"', and may or may
diff --git a/utf8.h b/utf8.h
index 7773007..d0b8742 100644 (file)
--- a/utf8.h
+++ b/utf8.h
@@ -501,13 +501,16 @@ only) byte is pointed to by C<s>.
 /*
 
 =for apidoc Am|STRLEN|UTF8_SAFE_SKIP|char* s|char* e
-returns the number of bytes in the UTF-8 encoded character whose first (perhaps
-only) byte is pointed to by C<s>.  But never returns beyond C<e>.
+returns 0 if S<C<s E<gt>= e>>; otherwise returns the number of bytes in the
+UTF-8 encoded character whose first  byte is pointed to by C<s>.  But it never
+returns beyond C<e>.  On DEBUGGING builds, it asserts that S<C<s E<lt>= e>>.
 
 =cut
  */
-#define UTF8_SAFE_SKIP(s, e)  (__ASSERT_((e) > (s))             \
-                               MIN(((e) - (s)), UTF8_SKIP(s)))
+#define UTF8_SAFE_SKIP(s, e)  (__ASSERT_((e) >= (s))                \
+                              ((e) - (s)) <= 0                      \
+                               ? 0                                  \
+                               : MIN(((e) - (s)), UTF8_SKIP(s)))
 
 /* Most code that says 'UNI_' really means the native value for code points up
  * through 255 */