01300: Incomplete definition of page text variable halts the rendering

Summary: Incomplete definition of page text variable halts the rendering
Created: 2012-10-12 04:31
Status: Open
Category: Bug
From: fberard?
Priority: 3
Version: 2.2.24
OS: OSX/Apache2.2.21/PHP5.3.10


Problem occur when a hidden page text variable is incompletely defined: when a substitution of the variable appears in the wiki code, the variable is not substituted (ok), but the remainder of the wiki is ignored (bug).

This is especially a problem when using a page text variable that is editable by students in a page that is only editable by administrators. In the following example, the rendering of the "Admin.JohnDoe" page stops at "birth date:".

Suggestion: incomplete definitions of page text variables should be ignored. In the example, the "birth_date" variable definition in "Student.JohnDoe" should be treated as if no variable definition existed, and the substitution in "Admin.JohnDoe" should substitute to empty (same as when substituting an undefined variable).

=== Student.JohnDoe

(:birth_date: Jan 1, 1998

=== Admin.JohnDoe

Student JohnDoe

birth date:

remainder of the page, this is not displayed due to bug. (remove the [= protection in the wiki code to see the bug).

I have marked the bug as confirmed, although at first sight I could not see how/why it happens -- the text shouldn't disappear according to the markup definition. I need to investigate this. --Petko October 12, 2012, at 05:52 AM

When a hidden PageTextVariable is started, the markup engine looks for the first ":)" in order to hide the variable. This means that any directive like (:table:), (:cell:), (:if:), (:div:), (:include:), (:linebreaks:), (:input:), another (:pagetextvar:iable:), or recipes like (:thumblist:) will have a ":)" which will cause more than what is expected to be hidden.

Even when there are no such directives in the page itself, when the markup is processed, the wikitext is not only what the page contains, there is more, notably (:include GroupFooter:) and (:closeall:) and so there is always ":)" somewhere later in the page.

I am not really sure if there is a way to fix this, except by placing ":)" or "%comment% :) %%" after the area editable by the students. I'm not sure how a student can edit a variable if only admins can edit the page, but if they edit it via PmForm, these problematic cases are handled automatically.

Alternatively, it is possible to add a new PageTextVariable markup, and use it instead of (:ptv:value:).

For example, if you want to enable this [:PTVname:PTVvalue:] format for PageTextVariables, here is what you add to config.php:

  Markup('[textvar:', '<textvar:',
    '/\\[: *\\w[-\\w]* *:(?!\\)).*?:\\]/s', '');
  $PageTextVarPatterns['[:var:...:]'] = 
    '/(\\[: *(\\w[-\\w]*) *:(?!\\))\\s?)(.*?)(:\\])/s';

This will add the new format without removing the default one. I'll keep thinking if something else could be done. --Petko May 08, 2013, at 07:08 AM

HansB June 24, 2017, at 11:03 AM:I corrected $PageTextVarPatterns['[:var:...:]'], so now it works (swapped ) and ] at the end). I had a similar pattern added for FoxForum, to be able to keep markup directives inside this custom PTV. As PTVs of form (:var:...:) can span multiple lines, and cannot have directives inside them, would it perhaps be feasable to have the regex recognise a (: as an end, not searching further for a closing :), and also not killing the rendering of the directive, whose beginning it may have found? I know this does not solve the original example problem, but it will leave any directives included, by mistake, still functioning. - I cannot quite work out the regex pattern, if I use a lookahead for (:, the next directive will not render, which I do not understand.

If this is still a problem, one way to help at least against accidential incomplete pagevar definitions could be to use a definition list of the form

:VarName: Text text text…
:AnotherVar: Text text text…

and hide it with (:if false:)(:ifend:). This way the aspects of definition and hiding are split to separate markups, the hiding part can be far apart from the lines meant to be edited, and the definition part looks more intuitively correct to untrained human readers. — Sven June 24, 2017, at 05:00 PM

I first made a change that will consider any "(:" as an end to the current textvar, and the next directive functions, or the next textvar starts (svn r3275). However, this didn't resolve the problem here, as we cannot assume where the textvar ends and a large text disappears from the page anyways. Then I modified the patterns to ignore stuff that starts like a textvar but at some point there is a "(:" instead of ":)" -- the text is not parsed as a textvar and is not hidden from the page. This is how it should be, this is not a real textvar, so let it be, instead of assuming what the person wants or not, and possibly break recipes built with Fox or PmForm or something else. See below. --Petko June 25, 2017, at 01:27 AM

(: PTV1:cool
cool (in parentheses)

(: PTV2 :cool

b4 include
(:include {$Name} lines=2..2:)


(:PTV3: Text formatting rules: [+big+]   [++bigger++]   [-small-]   [--smaller--]   '^superscript^'   '_subscript_'   {+inserted+}   {-deleted-}

(: PTV2 :cool cool cool

b4 include

Created: 2012-10-12 04:31

cool cool (in parentheses) cool

cool cool cool

b4 include (:include 01300 lines=2..2

(:PTV3: Text formatting rules: big bigger small smaller superscript subscript inserted deleted

The changes are in pmwiki.php:160 $PageTextVarPatterns and in stdmarkup.php:59 "textvar:" markup rule. BTW, there are some bad a.s.s. regular expressions. --Petko June 25, 2017, at 01:34 AM

Unfortunately, my fix appears to work only when the content of the text variable is 2699 bytes or less. If there are 2700 characters (or more), then the Regex engine appears to crash and the full page comes out blank, or on some installations, reportedly an internal server error is observed. I'm reverting this change for 2.2.102. --Petko August 05, 2017, at 05:08 AM