[pmwiki-devel] strange conversions: a FmtPageName bug

Hans design5 at softflow.co.uk
Thu May 8 04:17:27 CDT 2008


Thursday, May 8, 2008, 8:38:56 AM, Peter wrote:

> Any thoughts on this?  Does it fill a need or do most recipe authors prefer
> to just handle their own substitutions on user-supplied data?

I think it may be good to have a safe function.
How about a convenience function like this:

function FmtSafePageName($pagename, $fmt) {
   $fmt = str_replace('$','$',htmlspecialchars($fmt, ENT_NOQUOTES));
   return FmtPageName($fmt, $pagename );
}

(I reversed the arguments, as I always get confused with FmtPageName
wanting pagename last, and all other functions want it first)

You can test it with markup

# (:fmtsafe .... :)
Markup('fmtsafe','directives',
  '/\\(:fmtsafe\\s(.*?):\\)/ei',
  " FmtSafePageName(\$pagename, PSS('$1') )");

compared to

Markup('fmttest','directives',
  '/\\(:fmttest\\s(.*?):\\)/ei',
  " FmtPageName(PSS('$1'), \$pagename )");

Example:
for instance with markup on page Main.TitleTest

(:title {$FullName} :)
1 {$Title}
2 (:fmtsafe {$Title}:)
3 (:fmtsafe $Title:)

4 (:fmttest {$Title}:)
5 (:fmttest $Title:)

resulted output is:

1 Main.TitleTest
2 Main.TitleTest
3 $Title

4 Main.TitleTest
5 Main.TitleTest

3 (:fmtsafe $Title:) shows the defusing of a global variable as input.
Page variables and page text variables get rendered fine.

5 (:fmttest $Title:) substitutes a global variable. Any global can be
shown with (:fmttest ... :)

Regards to the other issues raised by this topic:

I hope that initialization within functions and variable substitutions
for capital first letter variables only in FmtPageName can be
implemented for the PmWiki 2.2 release.

I also think that a less aggressive variable substitution in
FmtPageName, using

  foreach($g as $k => $v)
          $fmt = preg_replace( "/\\$k\\b/", $v, $fmt);

instead of
  $fmt = str_replace(array_keys($g),array_values($g),$fmt);

is not really as inefficient in processing time as Patrick thinks.
At least my stopwatch tests showed hardly a difference.


Finally i recommend replacing the (:title ...:) markup with a safe
alternative which does not allow global var injections. At the same
time we can change its behaviour, so that the first (:title :) markup
always wins over subsequent (:title :) markups.

Here is my suggestion:

## (:title ...:) First title wins, any subsequent (:title ...:) is ignored.
Markup('title','directives',
  '/\\(:title\\s(.*?):\\)/ei',
  "SetRelativeTitle(\$pagename, PSS('$1')) ");
function SetRelativeTitle ($pagename, $arg) {
        static $tset = 1;
        $arg = str_replace('$','$',htmlspecialchars($arg, ENT_NOQUOTES));
        if ($tset==1)
                PCache($pagename, $zz=array('title' => SetProperty($pagename, 'title', $arg )));
        $tset++;
}


Hans




More information about the pmwiki-devel mailing list