Make MagicWordArray compatible with PCRE 8.34+
authorKevin Israel <pleasestand@live.com>
Sun, 22 Dec 2013 06:24:07 +0000 (01:24 -0500)
committerTim Starling <tstarling@wikimedia.org>
Tue, 31 Dec 2013 05:28:23 +0000 (05:28 +0000)
In PCRE 8.34, a subpattern's name must not start with a digit; work around
this by replacing digits in the synonym's index with letters. Amazingly,
this part of the name seems to have the sole purpose of ensuring uniqueness;
none of the matching functions actually use it for anything.

Adding a single-letter prefix was considered, though it would risk breaking
extension code that may have used 29- or 30- character magic word IDs.
(PCRE limits subpattern names to 32 characters.) Likewise, moving the magic
word's ID to the front would not work if it were to start with a digit.

Bug: 58640
Change-Id: Ic69f9000addbf18c4747105187e6f13191828fbb

RELEASE-NOTES-1.23
includes/MagicWord.php

index 3083551..a43ab03 100644 (file)
@@ -76,6 +76,8 @@ production.
 * (bug 37812) ResourceLoader will notice when a module's definition changes and
   recompile it accordingly.
 * (bug 57201) SpecialRecentChangesFilters hook is now executed for feeds.
+* (bug 58640) Fixed a compatibility issue with PCRE 8.34 that caused pages
+  to appear blank or with missing text.
 
 === API changes in 1.23 ===
 * (bug 54884) action=parse&prop=categories now indicates hidden and missing
index 427a1ad..232f43e 100644 (file)
@@ -709,7 +709,9 @@ class MagicWordArray {
                                $magic = MagicWord::get( $name );
                                $case = intval( $magic->isCaseSensitive() );
                                foreach ( $magic->getSynonyms() as $i => $syn ) {
-                                       $group = "(?P<{$i}_{$name}>" . preg_quote( $syn, '/' ) . ')';
+                                       // Group name must start with a non-digit in PCRE 8.34+
+                                       $it = strtr( $i, '0123456789', 'abcdefghij' );
+                                       $group = "(?P<{$it}_{$name}>" . preg_quote( $syn, '/' ) . ')';
                                        if ( $this->baseRegex[$case] === '' ) {
                                                $this->baseRegex[$case] = $group;
                                        } else {