[pmwiki-users] Irreproducible behavior - maybe a bug

Joachim Durchholz jo at durchholz.org
Wed May 11 15:07:43 CDT 2005


Patrick R. Michaud wrote:
 > I also wonder about the preg_replace you have above -- given
 >
 >
 >>  $MailForm2[$field . 'Text']
 >>    = '<input size="$size" value="$text"$attrs>';
 >>  $replacement =
 >>    preg_replace(
 >>      array('/\\$text/', '/\\$size/', '/\\$attrs/'),
 >>      array(htmlentities($MailForm2[$field . 'Text']), $size, $attrs),
 >>      $html
 >>    );
 >
 > since '$text' is being replaced by $MailForm2[$field . 'Text'], and
 > that value itself contains the string '$text' in it, I wonder if there
 > might be some bizarre loop or occurrence there as well.

Actually $MailForm2[$field . 'Text'] is the same as $text, but that's 
OK: it's not '$text' but $text that gets replaced. The preg_replace call 
  should actually have read
   preg_replace(
     array('/\\$text/', '/\\$size/', '/\\$attrs/'),
     array($text, $size, $attrs),
     $html
   );
(the poor man's version of variable substitution in a string).

To confirm that assumption, changing the code to the above didn't make 
the problem go away.


Here's the promised better variable dump.


I laced both the Markup() function and my code with var_dump calls, like 
this:

--- snip ---
function Markup($id,$cmd,$pat=NULL,$rep=NULL) {
   global $MarkupTable,$MarkupRules;
echo "\nStarting Markup, parameters are:\n";
echo "  id:  "; var_dump($id);
echo "  cmd: "; var_dump($cmd);
echo "  pat: "; var_dump($pat);
echo "  rep: "; var_dump($rep);
   unset($MarkupRules);
   if (preg_match('/^([<>])?(.+)$/',$cmd,$m)) {
     $MarkupTable[$id]['cmd']=$cmd;
     $MarkupTable[$m[2]]['dep'][$id] = $m[1];
     if (!$m[1]) $m[1]='=';
     if (@$MarkupTable[$m[2]]['seq']) {
echo "Recursing, printing some local data:\n";
       $MarkupTable[$id]['seq'] = $MarkupTable[$m[2]]['seq'].$m[1];
if (isset($MarkupTable[$id])) {
echo "  MarkupTable[id] exists\n";
echo "  MarkupTable[id]:                "; var_dump($MarkupTable[$id]);
echo "  MarkupTable[id]['dep']:         "; 
var_dump($MarkupTable[$id]['dep']);
echo "  (array) MarkupTable[id]['dep']: "; 
var_dump((array)$MarkupTable[$id]['d
}
       foreach((array)@$MarkupTable[$id]['dep'] as $i=>$m) {
echo "    i: "; var_dump($i);
echo "    m: "; var_dump($m);
         Markup($i,"$m$id");
       }
       unset($MarkupTable[$id]['dep']);
echo "Recursion done\n";
     }
   }
   if ($pat && !isset($MarkupTable[$id]['pat'])) {
     $MarkupTable[$id]['pat']=$pat;
     $MarkupTable[$id]['rep']=$rep;
   }
echo "End Markup()\n\n\n";
}
--- snip ---
echo "text:        "; var_dump($text);
echo "size:        "; var_dump($size);
echo "attrs:       "; var_dump($attrs);
echo "field:       "; var_dump($field);
echo "html:        "; var_dump($html);
echo "*** This works: ***\n";
   Markup(
     'mailform2-To',
     '>links',
     '/\\(:mailform2\sTo:\\)/i',
     '<input size="" value="" style="visibility:none">');
echo "*** Done with 'This works' ***\n";

   $replacement =
     preg_replace(
       array('/\\$text/', '/\\$size/', '/\\$attrs/'),
       array($text, $size, $attrs),
       $html
     );
echo "replacement: "; var_dump($replacement);
echo "*** This uses the same parameter values, but recurses endlessly: 
***\n";
   Markup(
     "mailform2-$field",
     '>links',
     '/\\(:mailform2\\s' . $field . ':\\)/i',
     $replacement);
echo "*** Done with 'This doesn't work' (well, we never get here) ***\n";
--- snip ---

and got this output (output from previous calls to Markup() snipped) (oh 
yeah, and I forced it to emit text/plain to avoid HTMLisation issues) 
(and I rectified some indenting since var_dump() can't accept a "base 
indent" parameter) (plus I inserted comment lines that start with ###):

--- snip ---
text:        string(0) ""
size:        NULL
attrs:       string(24) " style="visibility:none""
field:       string(2) "To"
html:        string(40) "<input size="$size" value="$text"$attrs>"
*** This works: ***

Starting Markup, parameters are:
   id:  string(12) "mailform2-To"
   cmd: string(6) ">links"
   pat: string(22) "/\(:mailform2\sTo:\)/i"
   rep: string(48) "<input size="" value="" style="visibility:none">"
Recursing, printing some local data:
   MarkupTable[id] exists
   MarkupTable[id]:                array(2) {
     ["cmd"]=>
     string(6) ">links"
     ["seq"]=>
     string(7) "B>>>>>>"
   }
   MarkupTable[id]['dep']:         NULL
   (array) MarkupTable[id]['dep']: array(0) {
   }
Recursion done
End Markup()
### I'm assuming that this output is what *should* show,
### given the var_dump() lacing in Markup(), above.


*** Done with 'This works' ***
replacement: string(48)
   "<input size="" value="" style="visibility:none">"
### As you can see, the $replacement string is pretty standard.
*** This uses the same parameter values, but recurses endlessly: ***

Starting Markup, parameters are:
   id:  string(12) "mailform2-To"
   cmd: string(6) ">links"
   pat: string(22) "/\(:mailform2\sTo:\)/i"
   rep: string(48) "<input size="" value="" style="visibility:none">"
### The above is the same as in the "This works" section.
Recursing, printing some local data:
   MarkupTable[id] exists
   MarkupTable[id]:                array(4) {
     ["cmd"]=>
     string(6) ">links"
     ["seq"]=>
     string(7) "B>>>>>>"
     ["pat"]=>
     string(22) "/\(:mailform2\sTo:\)/i"
     ["rep"]=>
     string(48) "<input size="" value="" style="visibility:none">"
   }
   MarkupTable[id]['dep']:         NULL
### OK, $MarkupTable[$id]['dep'] is NULL,
   (array) MarkupTable[id]['dep']: array(1) {
     [0]=>
     string(0) ""
   }
### ... but the type cast gives us array(0 => "")???
     i: int(0)
     m: string(0) ""
### To the foreach loop it looks like array(0 => ""), too.

Starting Markup, parameters are:
   id:  int(0)
   cmd: string(12) "mailform2-To"
### $id and $cmd are bogus values,
### so we better not expect anything sensible from here...
   pat: NULL
   rep: NULL
Recursing, printing some local data:
   MarkupTable[id] exists
   MarkupTable[id]:                array(2) {
     ["cmd"]=>
     string(12) "mailform2-To"
     ["seq"]=>
     string(8) "B>>>>>>="
   }
   MarkupTable[id]['dep']:         NULL
### Again, the value is NULL...
   (array) MarkupTable[id]['dep']: array(1) {
       [0]=>
       string(0) ""
     }
### ...but (array) gets array(0 => "")...
     i: int(0)
     m: string(0) ""
### ... and foreach ends up the same, again.
### Same situation as above, we again enter into Markup()
### with the same parameters, recursive loop closed.
--- snip ---

I've got a tentative prime suspect: the array cast. (In Markup(), it's 
even error-suppressed using @, but that doesn't seem to enter into the 
picture - I don't particularly like that use of @ though. It can mask 
errors other than the expected ones, and then ugly things start to happen.)

I'll test that hypothesis shortly.

Regards,
Jo



More information about the pmwiki-users mailing list