Skip to content

Commit

Permalink
Item14398: Better compatibility with friendly parser.
Browse files Browse the repository at this point in the history
Adjust the friendly parser to better support quoted strings. Make sure
that the first positional string, quoted or unquoted, when not followed
by an operator, is considered the _DEFAULT string rather that a boolean.

INCLUDE, ENCODE and ICONURL can all use the friendly parser now.  In
addition, fix the Fn_ENCODE::test_coverage test to not check hex 01-03.
These are escape values used by Render, RenderZone and Attrs parser.

SpreadSheetPlugin should us the classic parser.  It never has more than
a single parameter, quoted or unquoted.   It might be better to use the
_RAW value and not even try to parse the CALCULATE macro. But that's for
another time.

Tests for Fn_INCLUDE fixed to also support single-quoted operands.
  • Loading branch information
gac410 committed Jul 13, 2017
1 parent bf4a920 commit f8a843c
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 36 deletions.
8 changes: 1 addition & 7 deletions SpreadSheetPlugin/lib/Foswiki/Plugins/SpreadSheetPlugin.pm
Expand Up @@ -34,12 +34,6 @@ sub initPlugin {
# Get plugin debug flag
$debug = Foswiki::Func::getPreferencesFlag("SPREADSHEETPLUGIN_DEBUG") || 0;

my $legacyParser =
Foswiki::Func::isTrue(
Foswiki::Func::getPreferencesFlag("SPREADSHEETPLUGIN_LEGACYPARSER") )
|| $Foswiki::cfg{UseLegacyMacroParser}
|| '0';

# Following code is for a registered tag handler that does the same as
# CALC but in a tag handler instead of in commonTagsHandler. That means
# you can't use table references, but you can rely on the execution order
Expand All @@ -54,7 +48,7 @@ sub initPlugin {
return Foswiki::Plugins::SpreadSheetPlugin::Calc::_doCalc(
$attributes->{_DEFAULT} );
},
($legacyParser) ? 'classic' : 'context-free'
'classic'
);

# Flag to skip calc if in include
Expand Down
12 changes: 6 additions & 6 deletions UnitTestContrib/test/unit/AttrsTests.pm
Expand Up @@ -27,19 +27,19 @@ sub test_boolean {
my $this = shift;

my $attrs = Foswiki::Attrs->new( "a", 1 );
$this->assert( !$attrs->isEmpty() );
$this->assert_not_null( $attrs->{"a"} );
$this->assert_str_equals( "1", $attrs->{"a"} );

# First value is default,
$this->assert_not_null( $attrs->{"_DEFAULT"} );

$attrs = Foswiki::Attrs->new( "a12g b987", 1 );
$this->assert_not_null( $attrs->remove("a12g") );
$this->assert_null( $attrs->{"a12g"} );
$this->assert_str_equals( "a12g", $attrs->remove("_DEFAULT") );
$this->assert_null( $attrs->{"_DEFAULT"} );
$this->assert_not_null( $attrs->remove("b987") );
$this->assert_null( $attrs->{"b987"} );
$this->assert( $attrs->isEmpty(), "Fail " . $attrs->stringify() );

$attrs = Foswiki::Attrs->new( "Acid AnhydrousCopperSulphate='white' X", 1 );
$this->assert_not_null( $attrs->remove("Acid") );
$this->assert_str_equals( "Acid", $attrs->remove("_DEFAULT") );
$this->assert_not_null( $attrs->remove("X") );
$this->assert_str_equals( 'white',
$attrs->remove("AnhydrousCopperSulphate") );
Expand Down
14 changes: 8 additions & 6 deletions UnitTestContrib/test/unit/Fn_ENCODE.pm
Expand Up @@ -107,13 +107,15 @@ sub test_coverage {
);

# Same encoding, using the %ENCODE macro
#SMELL: Hex 01-02 are special markers used in render and don't encode correctly
#SMELL: Hex 01-03 are special markers used in render, and render zone, and don't encode correctly
$str = substr( $str, 3 ); # Drop first three characters
# Embedded double-quotes need escapes, so the macro gets the complete strings.
$str =~ s/\"/\\"/g;
$results =
$this->{test_topicObject}
->expandMacros( '%ENCODE{"' . $str . '" type="entities"}%' );

$this->assert_str_equals(
"'"	'0a''0d' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'7f'",
"	'0a''0d' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'7f'",
hexdump($results)
);

Expand All @@ -123,7 +125,7 @@ sub test_coverage {
->expandMacros( '%ENCODE{"' . $str . '" type="html"}%' );

$this->assert_str_equals(
"'"	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'7f'",
"	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'7f'",
hexdump($results)
);

Expand All @@ -133,7 +135,7 @@ sub test_coverage {
->expandMacros( '%ENCODE{"' . $str . '" type="url"}%' );

$this->assert_str_equals(
"%27%22%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f%20!%22%23%24%25%26%27%28%29*%2b%2c-./0123456789:%3b%3c%3d%3e%3f%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5b%5c%5d%5e_%60abcdefghijklmnopqrstuvwxyz%7b%7c%7d~%7f",
"%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f%20!%22%23%24%25%26%27%28%29*%2b%2c-./0123456789:%3b%3c%3d%3e%3f%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5b%5c%5d%5e_%60abcdefghijklmnopqrstuvwxyz%7b%7c%7d~%7f",
hexdump($results)
);

Expand All @@ -149,7 +151,7 @@ sub test_coverage {
->expandMacros( '%ENCODE{"' . $str . '" type="safe"}%' );

$this->assert_str_equals(
"'"'03''04''05''06''07''08''09''0a''0b''0c''0d''0e''0f''10''11''12''13''14''15''16''17''18''19''1a''1b''1c''1d''1e''1f' !"#\$%&'()*+,-./0123456789:;<=>?\@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'7f'",
"'04''05''06''07''08''09''0a''0b''0c''0d''0e''0f''10''11''12''13''14''15''16''17''18''19''1a''1b''1c''1d''1e''1f' !"#\$%&'()*+,-./0123456789:;<=>?\@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'7f'",
hexdump($results)
);

Expand Down
4 changes: 3 additions & 1 deletion UnitTestContrib/test/unit/Fn_INCLUDE.pm
Expand Up @@ -686,12 +686,14 @@ THIS

sub test_singlequoted_params {
my $this = shift;

# Note: with friendly parser, single quotes work fine too.
my $text =
$this->{test_topicObject}
->expandMacros("%INCLUDE{'Oneweb.SomeTopic' section='suction'}%");
$this->assert_str_equals(
"<span class='foswikiAlert'>
Warning: Can't INCLUDE '<nop>'Oneweb.SomeTopic' section='suction'', path is empty or contains illegal characters.
Warning: Can't find topic <nop>Oneweb.<nop>SomeTopic
</span>", $text
);

Expand Down
56 changes: 43 additions & 13 deletions core/lib/Foswiki/Attrs.pm
Expand Up @@ -55,7 +55,9 @@ BEGIN {
}
}

# Used in interpolation an regexes, so constant not appropriate
use constant TRACE => 0;

# Used in interpolation and regexes, so constant not appropriate
our $MARKER = "\0";

=begin TML
Expand Down Expand Up @@ -90,6 +92,7 @@ sub new {
else {
_unfriendly( $this, $string );
}

for ( values %$this ) {
s/\x01/'/g;
s/\x02/"/g;
Expand Down Expand Up @@ -193,13 +196,14 @@ sub _friendly {
my $key = "_DEFAULT";

while ( $string =~ m/\S/s ) {
print "STRING is ($string)\n" if (TRACE);

# name $op "value" pairs
if ( $string =~ s/^[\s,]*([#a-z0-9_]+)\s*($nameOp)\s*\"(.*?)\"//is ) {
$key = $1;
$Ops{$2}[0]( \$this->{$key}, $3 );

#print STDERR "Match1 $key\n";
print STDERR "Match1 $key - Name op DQ-Value\n" if (TRACE);
}

# simple double-quoted value with no name, sets the default
Expand All @@ -208,7 +212,7 @@ sub _friendly {
$key = '_DEFAULT';
$this->{_DEFAULT} = $1;

#print STDERR "Match2 $key\n";
print STDERR "Match2 $key DQ-value ($1).\n" if (TRACE);
}
}

Expand All @@ -217,7 +221,7 @@ sub _friendly {
$key = $1;
$Ops{$2}[0]( \$this->{$key}, $3 );

#print STDERR "Match3 $key\n";
print STDERR "Match3 $key - Name op SQ-Value\n" if (TRACE);
}

# name $op value pairs
Expand All @@ -227,50 +231,75 @@ sub _friendly {
$key = $1;
$Ops{$2}[0]( \$this->{$key}, $3 );

#print STDERR "Match4 $key\n";
print STDERR "Match4 $key - name op NQ-value\n" if (TRACE);
}

# $op "value"
elsif ( $string =~ s/^[\s,]*($nonmOp)\s*\"(.*?)\"//is ) {
$Ops{$1}[1]( \$this->{$key}, $2 );

#print STDERR "Match5 $key\n";
print STDERR "Match5 $key - op DQ-Value\n" if (TRACE);
}

# $op 'value'
elsif ( $string =~ s/^[\s,]*($nonmOp)\s*'(.*?)'//is ) {
$Ops{$1}[1]( \$this->{$key}, $2 );

#print STDERR "Match6 $key\n";
print STDERR "Match6 $key - op SQ-Value\n" if (TRACE);
}

# $op value
elsif ( $string =~ s/^[\s,]*($nonmOp)\s*([^\s,\}\'\"]*)//is ) {
$Ops{$1}[1]( \$this->{$key}, $2 );

#print STDERR "Match7 $key\n";
print STDERR "Match7 $key - op NQ-Value\n" if (TRACE);
}

# simple single-quoted value with no name, sets the default
elsif ( $string =~ s/^[\s,]*'(.*?)'//s ) {
unless ( defined( $this->{_DEFAULT} ) ) {
if ( defined( $this->{_DEFAULT} ) ) {
$this->{$1} = 1;
print STDERR "Match8a $1 - SQ-value, already have _DEFAULT\n"
if (TRACE);
}
else {
$key = '_DEFAULT';
$this->{_DEFAULT} = $1;

#print STDERR "Match8 $key\n";
print STDERR "Match8b $key - SQ-Value\n" if (TRACE);
}
}

# simple name with no value (boolean, or _DEFAULT)
elsif ( $string =~ s/^[\s,]*([a-z][a-z0-9_]*)\b//is ) {
elsif ( $string =~ s/^[\s,]*([a-z][a-z0-9_]*)(?=[\s,])//is ) {

if ( defined( $this->{_DEFAULT} ) ) {
$this->{$1} = 1;
print STDERR
"Match9a $1 - name, no value, already have _DEFAULT\n"
if (TRACE);
}
else {
$key = '_DEFAULT';
$this->{_DEFAULT} = $1;
print STDERR "Match9b $1 - name, no value, take as _DEFAULT\n"
if (TRACE);
}
}

#print STDERR "Match9 $1\n";
# string with no value (boolean, or _DEFAULT)
elsif ( $string =~ s/^[\s,]*([\S]*)//is ) {
if ( defined( $this->{_DEFAULT} ) ) {
$this->{$1} = 1;
print STDERR
"Match10 $1 string, no value, already have _DEFAULT$1\n"
if (TRACE);
}
else {
$key = '_DEFAULT';
$this->{_DEFAULT} = $1;
print STDERR "Match10 $1 string, no value, take as _DEFAULT$1\n"
if (TRACE);
}
}

Expand All @@ -283,7 +312,8 @@ sub _friendly {
{
$this->{_DEFAULT} = $1;

#print STDERR "Match10 $1\n";
print STDERR "Match10 $1 - Whole string is default\n"
if (TRACE);
}
last;
}
Expand Down
2 changes: 1 addition & 1 deletion core/lib/Foswiki/Macros/ENCODE.pm
Expand Up @@ -6,7 +6,7 @@ use warnings;
my @DIG = map { chr($_) } ( 0 .. 9 );

# Macro takes unquoted default parameter - context-free not supported.
$Foswiki::contextFreeSyntax{ENCODE} = 0;
#$Foswiki::contextFreeSyntax{ENCODE} = 0;

BEGIN {
if ( $Foswiki::cfg{UseLocale} ) {
Expand Down
2 changes: 1 addition & 1 deletion core/lib/Foswiki/Macros/ICONURL.pm
Expand Up @@ -7,7 +7,7 @@ use warnings;
use Foswiki::Macros::ICON ();

# Macro takes unquoted default parameter - context-free not supported.
$Foswiki::contextFreeSyntax{ICONURL} = 0;
#$Foswiki::contextFreeSyntax{ICONURL} = 0;

BEGIN {
if ( $Foswiki::cfg{UseLocale} ) {
Expand Down
2 changes: 1 addition & 1 deletion core/lib/Foswiki/Macros/INCLUDE.pm
Expand Up @@ -8,7 +8,7 @@ use Foswiki::Render;
use Foswiki::Func;

# Macro takes unquoted default parameter - context-free not supported.
$Foswiki::contextFreeSyntax{INCLUDE} = 0;
#$Foswiki::contextFreeSyntax{INCLUDE} = 0;

BEGIN {
if ( $Foswiki::cfg{UseLocale} ) {
Expand Down

0 comments on commit f8a843c

Please sign in to comment.