01149: Bugs in GlobToPCRE()

Summary: Bugs in GlobToPCRE()
Created: 2009-10-11 19:00
Status: Closed - added for 2.2.7
Category: Bug
From: Rogutės?
Assigned:
Priority: 45
Version: 2.2.6
OS:

Description:

Two problems with the GlobToPCRE() function:

  1. Since PHP-5.3, preg_quote() is escaping the '-' character, thus making exclusion pattterns impossible (the check $p{0}=='-' becomes invalid, because $p{0} now equals '\').
  2. Similarly, the comment above GlobToPCRE() definition proclaims that both, '-' and '!', can be used for exclusion, but '!' has always been escaped by the call to preg_quote().

Fixing suggestions:

  1. Add '\\-' to the first array argument of str_replace() and '-' to the second.
  2. Since this has always been broken, perhaps the comment should be fixed and the check for '!' removed from this conditional: if ($p{0} == '-' || $p{0} == '!') $excl[] = '^'.substr($p, 1).'$';.

Diff:

--- pmwiki.php.orig	2009-09-03 17:55:09.000000000 +0300
+++ pmwiki.php	2009-10-12 02:58:51.271884690 +0300
@@ -571,11 +571,11 @@
 ## GlobToPCRE converts wildcard patterns into pcre patterns for
-## inclusion and exclusion.  Wildcards beginning with '-' or '!'
-## are treated as things to be excluded.
+## inclusion and exclusion.  Wildcards beginning with '-' are 
+## treated as things to be excluded.
 function GlobToPCRE($pat) {
   $pat = preg_quote($pat, '/');
-  $pat = str_replace(array('\\*', '\\?', '\\[', '\\]', '\\^'),
-                     array('.*',  '.',   '[',   ']',   '^'), $pat);
+  $pat = str_replace(array('\\*', '\\?', '\\[', '\\]', '\\^', '\\-'),
+                     array('.*',  '.',   '[',   ']',   '^', '-'), $pat);
   $excl = array(); $incl = array();
   foreach(preg_split('/,+\s?/', $pat, -1, PREG_SPLIT_NO_EMPTY) as $p) {
-    if ($p{0} == '-' || $p{0} == '!') $excl[] = '^'.substr($p, 1).'$';
+    if ($p{0} == '-') $excl[] = '^'.substr($p, 1).'$';
     else $incl[] = "^$p$";

Should we remove the comment about "!", or is it better to just fix the code to enable the feature? We could add '\\!' to the first array argument of str_replace() and '!' to the second, then name="!*Variables" will work like originally planned. --Petko October 14, 2009, at 12:50 AM