Commit b159408a by seldaek

Fixed parsing of quoted keywords in if statements, like 'not' was parsed as !…

Fixed parsing of quoted keywords in if statements, like 'not' was parsed as ! because using {if not $foo} is valid, but it was impossible to use them even as string. Fixes #46. git-svn-id: http://svn.dwoo.org/trunk@329 0598d79b-80c4-4d41-97ba-ac86fbbd088b
parent 9364271e
[2009--] 1.2.0
! BC Break: Dwoo::isArray had to be fixed and it has been split up in 3
methods, isArray (for array access), isTraversable (for foreach) and
methods, isArray (for array access), isTraversable (for foreach) and
count (just a helper that counts anything). It won't affect you unless
you built some plugin depending on isArray, in which case you should
check all works fine still
* Fixed parsing of quoted keywords in if statements, like 'not' was
parsed as ! because using {if not $foo} is valid, but it was impossible
to use them even as string.
[2009--] 1.1.1
+ Added {optional} plugin that just prints an optional var without any
......@@ -13,17 +16,17 @@
around the parent template's filename
* Fixed a security issue, if you didn't use a custom compiler factory but
passed the compiler directly to the get method with autoEscape enabled,
the autoEscape was disabled in included templates - Thanks to Fabien
the autoEscape was disabled in included templates - Thanks to Fabien
Potencier for notifying me.
* Fixed a bug in {safe} when using variable-variables it would sometimes
* Fixed a bug in {safe} when using variable-variables it would sometimes
corrupt the var name resulting in blank output
* Fixed a bug when accessing array indices that contain a minus sign, it
is now possible to access those using {$var[index-foo]},
* Fixed a bug when accessing array indices that contain a minus sign, it
is now possible to access those using {$var[index-foo]},
{$var['index-foo']} or {$index="index-foo"} {$var[$index]}
* Fixed a bug in {tif} that didn't work when 0 was given as the true or
* Fixed a bug in {tif} that didn't work when 0 was given as the true or
false value
* Fixed a bug when using the autoEscape feature with sub-templates (the
compiled sub-template couldn't access the dwoo charset property,
* Fixed a bug when using the autoEscape feature with sub-templates (the
compiled sub-template couldn't access the dwoo charset property,
resulting in a fatal error)
* Fixed a property reading bug on objects that implemented __get but not
__isset, implementing __isset is however very much recommended
......@@ -34,7 +37,7 @@
within a dynamic block
* Fixed a {load_templates} bug, plugins used in external templates were not
loaded correctly, same for custom user plugins
* Cached templates now check the source template for modification before
* Cached templates now check the source template for modification before
outputting the cached version
* Removed a couple of @-operator calls to file_get_contents
......
......@@ -232,6 +232,17 @@ class Dwoo_Compiler implements Dwoo_ICompiler
protected static $instance;
/**
* token types
* @var int
*/
const T_UNQUOTED_STRING = 1;
const T_NUMERIC = 2;
const T_NULL = 4;
const T_BOOL = 8;
const T_MATH = 16;
const T_BREAKCHAR = 32;
/**
* constructor
*
* saves the created instance so that child templates get the same one
......@@ -1210,6 +1221,22 @@ class Dwoo_Compiler implements Dwoo_ICompiler
}
/**
* returns the token of each parameter out of the given parameter array
*
* @param array $params parameter array
* @return array tokens
*/
public function getParamTokens(array $params)
{
foreach ($params as $k=>$p) {
if (is_array($p)) {
$params[$k] = isset($p[2]) ? $p[2] : 0;
}
}
return $params;
}
/**
* entry point of the parser, it redirects calls to other parse* functions
*
* @param string $in the string within which we must parse something
......@@ -1468,9 +1495,10 @@ class Dwoo_Compiler implements Dwoo_ICompiler
}
$parts = $this->mapParams($parts, array('Dwoo_Plugin_if', 'init'), 1);
$tokens = $this->getParamTokens($parts);
$parts = $this->getCompiledParams($parts);
$value = Dwoo_Plugin_if::replaceKeywords($parts['*'], $this);
$value = Dwoo_Plugin_if::replaceKeywords($parts['*'], $tokens['*'], $this);
$echo = '';
} else {
$value = array();
......@@ -1581,7 +1609,8 @@ class Dwoo_Compiler implements Dwoo_ICompiler
if ($curBlock === 'condition') {
// load if plugin
$this->getPluginType('if');
if (Dwoo_Plugin_if::replaceKeywords(array($func), $this) !== array($func)) {
if (Dwoo_Plugin_if::replaceKeywords(array($func), array(self::T_UNQUOTED_STRING), $this) !== array($func)) {
return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
}
}
......@@ -1738,8 +1767,10 @@ class Dwoo_Compiler implements Dwoo_ICompiler
}
// only keep php-syntax-safe values for non-block plugins
foreach ($params as &$p) {
$p = $p[0];
$tokens = array();
foreach ($params as $k => $p) {
$tokens[$k] = isset($p[2]) ? $p[2] : 0;
$params[$k] = $p[0];
}
if ($pluginType & Dwoo::NATIVE_PLUGIN) {
if ($func === 'do') {
......@@ -1769,6 +1800,9 @@ class Dwoo_Compiler implements Dwoo_ICompiler
$funcCompiler = 'Dwoo_Plugin_'.$func.'_compile';
}
array_unshift($params, $this);
if ($func === 'tif') {
$params[] = $tokens;
}
$output = call_user_func_array($funcCompiler, $params);
} else {
array_unshift($params, '$this');
......@@ -2498,35 +2532,41 @@ class Dwoo_Compiler implements Dwoo_ICompiler
if (strtolower($substr) === 'false' || strtolower($substr) === 'no' || strtolower($substr) === 'off') {
if ($this->debug) echo 'BOOLEAN(FALSE) PARSED<br />';
$substr = 'false';
$type = self::T_BOOL;
} elseif (strtolower($substr) === 'true' || strtolower($substr) === 'yes' || strtolower($substr) === 'on') {
if ($this->debug) echo 'BOOLEAN(TRUE) PARSED<br />';
$substr = 'true';
$type = self::T_BOOL;
} elseif ($substr === 'null' || $substr === 'NULL') {
if ($this->debug) echo 'NULL PARSED<br />';
$substr = 'null';
$type = self::T_NULL;
} elseif (is_numeric($substr)) {
$substr = (float) $substr;
if ((int) $substr == $substr) {
$substr = (int) $substr;
}
$type = self::T_NUMERIC;
if ($this->debug) echo 'NUMBER ('.$substr.') PARSED<br />';
} elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) {
if ($this->debug) echo 'SIMPLE MATH PARSED<br />';
$type = self::T_MATH;
$substr = '('.$substr.')';
} elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) {
if ($this->debug) echo 'BREAKCHAR ('.$substr.') PARSED<br />';
$type = self::T_BREAKCHAR;
//$substr = '"'.$substr.'"';
} else {
$substr = $this->replaceStringVars('\''.str_replace('\'', '\\\'', $substr).'\'', '\'', $curBlock);
$type = self::T_UNQUOTED_STRING;
if ($this->debug) echo 'BLABBER ('.$substr.') CASTED AS STRING<br />';
}
if (is_array($parsingParams)) {
$parsingParams[] = array($substr, $src);
$parsingParams[] = array($substr, $src, $type);
return $parsingParams;
} elseif ($curBlock === 'namedparam') {
return array($substr, $src);
return array($substr, $src, $type);
} elseif ($curBlock === 'expression') {
return $substr;
} else {
......@@ -2988,12 +3028,14 @@ class Dwoo_Compiler implements Dwoo_ICompiler
}
$tmp = array();
$tmp2 = array();
$tmp3 = array();
foreach ($ps as $i=>$p) {
$tmp[$i] = $p[0];
$tmp2[$i] = $p[1];
$tmp3[$i] = isset($p[2]) ? $p[2] : 0;
unset($ps[$i]);
}
$paramlist[$v[0]] = array($tmp, $tmp2);
$paramlist[$v[0]] = array($tmp, $tmp2, $tmp3);
unset($tmp, $tmp2, $i, $p);
break;
} elseif (isset($ps[$v[0]])) {
......@@ -3019,7 +3061,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler
throw new Dwoo_Compilation_Exception($this, 'Argument '.$k.'/'.$v[0].' missing for '.str_replace(array('Dwoo_Plugin_', '_compile'), '', $name));
} elseif ($v[2]===null) {
// enforce lowercased null if default value is null (php outputs NULL with var export)
$paramlist[$v[0]] = array('null', null);
$paramlist[$v[0]] = array('null', null, self::T_NULL);
} else {
// outputs default value with var_export
$paramlist[$v[0]] = array(var_export($v[2], true), $v[2]);
......
......@@ -44,9 +44,10 @@ class Dwoo_Plugin_elseif extends Dwoo_Plugin_if implements Dwoo_ICompilable_Bloc
return '';
}
$tokens = $compiler->getParamTokens($params);
$params = $compiler->getCompiledParams($params);
$pre = Dwoo_Compiler::PHP_OPEN."elseif (".implode(' ', self::replaceKeywords($params['*'], $compiler)).") {\n" . Dwoo_Compiler::PHP_CLOSE;
$pre = Dwoo_Compiler::PHP_OPEN."elseif (".implode(' ', self::replaceKeywords($params['*'], $tokens['*'], $compiler)).") {\n" . Dwoo_Compiler::PHP_CLOSE;
$post = Dwoo_Compiler::PHP_OPEN."\n}".Dwoo_Compiler::PHP_CLOSE;
if (isset($params['hasElse'])) {
......
......@@ -33,7 +33,7 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
{
}
public static function replaceKeywords(array $params, Dwoo_Compiler $compiler)
public static function replaceKeywords(array $params, array $tokens, Dwoo_Compiler $compiler)
{
$p = array();
......@@ -48,53 +48,108 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
switch($vmod) {
case 'and':
$p[] = '&&';
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '&&';
} else {
$p[] = $v;
}
break;
case 'or':
$p[] = '||';
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '||';
} else {
$p[] = $v;
}
break;
case '==':
case 'eq':
$p[] = '==';
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '==';
} else {
$p[] = $v;
}
break;
case '<>':
case '!=':
case 'ne':
case 'neq':
$p[] = '!=';
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '!=';
} else {
$p[] = $v;
}
break;
case '>=':
case 'gte':
case 'ge':
$p[] = '>=';
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '>=';
} else {
$p[] = $v;
}
break;
case '<=':
case 'lte':
case 'le':
$p[] = '<=';
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '<=';
} else {
$p[] = $v;
}
break;
case '>':
case 'gt':
$p[] = '>';
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '>';
} else {
$p[] = $v;
}
break;
case '<':
case 'lt':
$p[] = '<';
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '<';
} else {
$p[] = $v;
}
break;
case '===':
$p[] = '===';
case 'mod':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '%';
} else {
$p[] = $v;
}
break;
case 'not':
if ($tokens[$k] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = '!';
} else {
$p[] = $v;
}
break;
case '<>':
$p[] = '!=';
break;
case '==':
case '!=':
case '>=':
case '<=':
case '>':
case '<':
case '===':
case '!==':
$p[] = '!==';
case '%':
case '!':
$p[] = $vmod;
break;
case 'is':
if (isset($params[$k+1]) && strtolower(trim($params[$k+1], '"\'')) === 'not') {
if ($tokens[$k] !== Dwoo_Compiler::T_UNQUOTED_STRING) {
$p[] = $v;
break;
}
if (isset($params[$k+1]) && strtolower(trim($params[$k+1], '"\'')) === 'not' && $tokens[$k+1] === Dwoo_Compiler::T_UNQUOTED_STRING) {
$negate = true;
next($params);
} else {
$negate = false;
}
$ptr = 1+(int)$negate;
if ($tokens[$k+$ptr] !== Dwoo_Compiler::T_UNQUOTED_STRING) {
break;
}
if (!isset($params[$k+$ptr])) {
$params[$k+$ptr] = '';
} else {
......@@ -141,14 +196,6 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
}
break;
case '%':
case 'mod':
$p[] = '%';
break;
case '!':
case 'not':
$p[] = '!';
break;
default:
$p[] = $v;
......@@ -165,9 +212,9 @@ class Dwoo_Plugin_if extends Dwoo_Block_Plugin implements Dwoo_ICompilable_Block
public static function postProcessing(Dwoo_Compiler $compiler, array $params, $prepend, $append, $content)
{
$tokens = $compiler->getParamTokens($params);
$params = $compiler->getCompiledParams($params);
$pre = Dwoo_Compiler::PHP_OPEN.'if ('.implode(' ', self::replaceKeywords($params['*'], $compiler)).") {\n".Dwoo_Compiler::PHP_CLOSE;
$pre = Dwoo_Compiler::PHP_OPEN.'if ('.implode(' ', self::replaceKeywords($params['*'], $tokens['*'], $compiler)).") {\n".Dwoo_Compiler::PHP_CLOSE;
$post = Dwoo_Compiler::PHP_OPEN."\n}".Dwoo_Compiler::PHP_CLOSE;
......
......@@ -18,7 +18,7 @@
* @date 2008-10-23
* @package Dwoo
*/
function Dwoo_Plugin_tif_compile(Dwoo_Compiler $compiler, array $rest)
function Dwoo_Plugin_tif_compile(Dwoo_Compiler $compiler, array $rest, array $tokens)
{
// load if plugin
if (!class_exists('Dwoo_Plugin_if', false)) {
......@@ -32,7 +32,7 @@ function Dwoo_Plugin_tif_compile(Dwoo_Compiler $compiler, array $rest)
if (count($rest) == 1) {
return $rest[0];
}
// fetch false result and remove the ":" if it was present
$falseResult = array_pop($rest);
......@@ -68,7 +68,7 @@ function Dwoo_Plugin_tif_compile(Dwoo_Compiler $compiler, array $rest)
}
// parse condition
$condition = Dwoo_Plugin_if::replaceKeywords($rest, $compiler);
$condition = Dwoo_Plugin_if::replaceKeywords($rest, $tokens, $compiler);
return '(('.implode(' ', $condition).') ? '.($trueResult===true ? implode(' ', $condition) : $trueResult).' : '.$falseResult.')';
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment