[pmwiki-users] Markup Processing Order
Patrick R. Michaud
pmichaud at pobox.com
Sun Aug 20 14:34:22 CDT 2006
On Sun, Aug 20, 2006 at 11:44:31AM -0400, The Editor wrote:
> I have a markup (:data Group.Name:) which pulls all the data fields
> off a given wiki page and sets them as page variables. Currently the
> processing order is set to
>
> '<{$var}'
>
> It works perfect for normal uses. The problem is, for some
> applications I need this:
>
> (:data Group.{$Name}:)
>
> When I actually got around to trying some of these applications I
> discovered it processes the data markup before translating $Name--thus
> giving me error messages as it tries to fread from literal:
> Group.{$Name}.
>
> I tried setting it to
>
> '>{$var}'
>
> thinking this would then set all the variables just after {$Name}--and
> it does gets rid of all the error messages--but too late to do
> anything with the page variables! That is, they show up blank,
> because the function is run after all the $var's have already been
> translated. I guess it's a problem of the chicken or the egg.
However, PmWiki already fixes this for you. :-)
You want it set to '>{$var}', so that it will occur after
page variable substitution, and the {$Name} will get correctly
substituted. However, as part of processing the (:data ...:)
directive, be sure to make a call to the PRR() function. This
tells the markup engine to *immediately restart* processing
the text with the first markup rule again. As a result, any
page variables that were included by the (:data:) markup will
get handled by this second pass through the {$var} rule (as well
as passing through the $[...] rule, the [=...=] rule, etc.)
Or, you can leave it set to '<{$var}', and have your ReadData
function do page variable substitutions on the parameter before
opening the appropriate page or file. Thus:
# Function called by directive to retrieve form data
function ReadData($l) {
global $WorkDir, $FmtPV;
$l = preg_replace('/\\{(!?[-\\w.\\/]*)(\\$\\w+)\\}/e',
"htmlspecialchars(PageVar(\$pagename, '$2', '$1'), ENT_NOQUOTES)");
$datapage = substr($l, 1);
if ($dr = fopen("$WorkDir/$datapage", "rb")){
$pc = fread($dr, filesize("$WorkDir/$datapage"));
Also, I should note that as written this function looks somewhat
insecure, since an author can pass any argument to ReadData()
and hence to fopen. For example:
(:data ../../../../../../etc/passwd :)
In fact, someone can easily use this to bypass PmWiki's
security checks and grab data from any read-protected page:
(:data ../wiki.d/Group.SomePage :)
Granted, the later processing will restrict what a malicious
person is able to access, but still, it's better to prevent
the opening of arbitrary files in the first place.
(:data ../../../../../dev/random:) # could read from here for a long time
Pm
More information about the pmwiki-users
mailing list