From 3f3f270fdac571f7742c26c0377a91fb47f6ffca Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 17 Jan 2023 00:00:34 +0900 Subject: [PATCH] Reduce warnings due to undefined variables in templates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 템플릿에서 변수를 단순 참조할 경우 ?? '' 를 붙여 워닝 방지 - 함수 호출이나 복잡한 문법 안에 들어간 변수까지 처리해 주지는 않음 - 불필요한 오류 메시지를 줄여서 정말 중요한 오류를 찾기 쉽도록 --- classes/template/TemplateHandler.class.php | 13 ++++- tests/unit/classes/TemplateHandlerTest.php | 68 +++++++++++----------- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/classes/template/TemplateHandler.class.php b/classes/template/TemplateHandler.class.php index c25e52a74..20e29281b 100644 --- a/classes/template/TemplateHandler.class.php +++ b/classes/template/TemplateHandler.class.php @@ -555,6 +555,10 @@ class TemplateHandler switch($stmt) { case 'cond': + if (preg_match('/^\$[\\\\\w\[\]\'":>-]+$/i', $expr)) + { + $expr = "$expr ?? false"; + } $nodes[$idx - 1] .= ""; break; case 'loop': @@ -779,11 +783,11 @@ class TemplateHandler if ($filter_option) { $filter_option = $this->_applyEscapeOption($filter_option, $escape_option); - $var = "'' . {$var} . ''"; + $var = "'' . ($var) . ''"; } else { - $var = "'' . {$var} . ''"; + $var = "'' . ($var) . ''"; } $escape_option = 'noescape'; break; @@ -1027,6 +1031,11 @@ class TemplateHandler */ private function _applyEscapeOption($str, $escape_option) { + if (preg_match('/^\$[\\\\\w\[\]\'":>-]+$/i', $str)) + { + $str = "$str ?? ''"; + } + switch($escape_option) { case 'escape': diff --git a/tests/unit/classes/TemplateHandlerTest.php b/tests/unit/classes/TemplateHandlerTest.php index 3dd3151f1..f5006943d 100644 --- a/tests/unit/classes/TemplateHandlerTest.php +++ b/tests/unit/classes/TemplateHandlerTest.php @@ -21,7 +21,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // cond array( 'Link1say, hello', - '?>Link1cond){ ?>say, hello' + '?>Link1cond ?? false){ ?>say, hello' ), // cond array( @@ -51,7 +51,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // ~ array( 'LinkHello, {$world}', - '?>Linkcond){ ?>Hello, world ?>' + '?>Linkcond){ ?>Hello, world ?? \'\' ?>' ), // ~ ~ array( @@ -71,12 +71,12 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // ~ array( '
  • item{$key} : {$val}
  • ', - PHP_EOL . 'if($__Context->arr)foreach($__Context->arr as $__Context->key=>$__Context->val){ ?>
  • itemkey ?> : val ?>
  • ' + PHP_EOL . 'if($__Context->arr)foreach($__Context->arr as $__Context->key=>$__Context->val){ ?>
  • itemkey ?? \'\' ?> : val ?? \'\' ?>
  • ' ), // ~ array( '{$v->text}', - PHP_EOL.'while($__Context->item=$__Context->list->getItem()){ ?>v->text ?>' + PHP_EOL.'while($__Context->item=$__Context->list->getItem()){ ?>v->text ?? \'\' ?>' ), // ~ ~ ~ ~ array( @@ -146,7 +146,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // self-closing tag array( '', - PHP_EOL . 'if($__Context->foo){ ?>' + PHP_EOL . 'if($__Context->foo ?? false){ ?>' ), // relative path1 array( @@ -161,7 +161,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // error case array( 'logo', - PHP_EOL . 'if($__Context->layout_info->logo_image){ ?>logo' + PHP_EOL . 'if($__Context->layout_info->logo_image ?? false){ ?>logo' ), // error case - ignore stylesheets array( @@ -186,7 +186,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // issue 135 array( '

    {$key}

    Loop block {$val}
    ', - PHP_EOL . '$__loop_tmp=$__Context->_m_list_all;if($__loop_tmp)foreach($__loop_tmp as $__Context->key=>$__Context->val){ ?>

    key ?>

    Loop block val ?>
    ' + PHP_EOL . '$__loop_tmp=$__Context->_m_list_all;if($__loop_tmp)foreach($__loop_tmp as $__Context->key=>$__Context->val){ ?>

    key ?? \'\' ?>

    Loop block val ?? \'\' ?>
    ' ), // issue 136 array( @@ -206,12 +206,12 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // issue 183 array( ''."\n".'
    {$vvv}
    CD
    ', - '?>vvvls;if($__loop_tmp)foreach($__loop_tmp as $__Context->vvv){ ?>'."\n".'
    vvv ?>
    CD
    ' + '?>vvvls;if($__loop_tmp)foreach($__loop_tmp as $__Context->vvv){ ?>'."\n".'
    vvv ?? \'\' ?>
    CD
    ' ), // issue 512 - ignores array( '
    {$lang->sl_show_topimgtext}
    ', - '?>
    sl_show_topimgtext ?>
    ' + '?>
    sl_show_topimgtext ?? \'\' ?>
    ' ), // issue 584 array( @@ -236,7 +236,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // https://github.com/xpressengine/xe-core/issues/1510 array( '', - PHP_EOL . 'if($__Context->foo->bar){ ?>' + PHP_EOL . 'if($__Context->foo->bar ?? false){ ?>' ), // https://github.com/xpressengine/xe-core/issues/1510 array( @@ -246,7 +246,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // https://github.com/xpressengine/xe-core/issues/1510 array( '', - PHP_EOL . 'if($__Context->foo->bar){ ?>' + PHP_EOL . 'if($__Context->foo->bar ?? false){ ?>' ), // https://github.com/xpressengine/xe-core/issues/1510 array( @@ -256,19 +256,19 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // https://github.com/xpressengine/xe-core/issues/1510 array( '', - PHP_EOL . 'if($__Context->mi->title){ ?>mi->use){ ?> class="tmp_class" src="' . $this->baseurl . 'tests/unit/classes/img/common/blank.gif" />' + PHP_EOL . 'if($__Context->mi->title ?? false){ ?>mi->use){ ?> class="tmp_class" src="' . $this->baseurl . 'tests/unit/classes/img/common/blank.gif" />' ), array( ' alt', - '?> foo->bar){ ?>alt' + '?> foo->bar ?? false){ ?>alt' ), array( '' . "\n" . ' alt', - '?>' . PHP_EOL . ' foo->bar){ ?>alt' + '?>' . PHP_EOL . ' foo->bar ?? false){ ?>alt' ), array( 'asf ', - '?>asf ' + '?>asf ' ), array( '', @@ -289,12 +289,12 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // srcset (PR #1544) array( 'this is a test image.', - '?>this is a test image.' + '?>this is a test image.' ), // Rhymix improvements (PR #604) array( '{$_SERVER["REMOTE_ADDR"]}', - '?>' + '?>' ), array( '{escape($_COOKIE[$var], false)}', @@ -306,7 +306,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test ), array( '{$FOOBAR}', - '?>FOOBAR ?>' + '?>FOOBAR ?? \'\' ?>' ), array( '{RX_BASEDIR}', @@ -331,20 +331,20 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test ), array( '
    • {$val}
    ', - "\n" . '$__loop_tmp=$__Context->foo->{$__Context->bar};if($__loop_tmp)foreach($__loop_tmp as $__Context->key=>$__Context->val){ ?>foo->{$__Context->key}){ ?> class="test">
  • val ?>
  • ' + "\n" . '$__loop_tmp=$__Context->foo->{$__Context->bar};if($__loop_tmp)foreach($__loop_tmp as $__Context->key=>$__Context->val){ ?>foo->{$__Context->key}){ ?> class="test">
  • val ?? \'\' ?>
  • ' ), // Rhymix autoescape array( '{$foo}', - PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo ($this->config->autoescape ? htmlspecialchars($__Context->foo, ENT_QUOTES, \'UTF-8\', false) : ($__Context->foo)) ?>' + PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo ($this->config->autoescape ? htmlspecialchars($__Context->foo ?? \'\', ENT_QUOTES, \'UTF-8\', false) : ($__Context->foo ?? \'\')) ?>' ), array( '{$foo}', - PHP_EOL . '$this->config->autoescape = false;' . "\n" . 'echo ($this->config->autoescape ? htmlspecialchars($__Context->foo, ENT_QUOTES, \'UTF-8\', false) : ($__Context->foo)) ?>' + PHP_EOL . '$this->config->autoescape = false;' . "\n" . 'echo ($this->config->autoescape ? htmlspecialchars($__Context->foo ?? \'\', ENT_QUOTES, \'UTF-8\', false) : ($__Context->foo ?? \'\')) ?>' ), array( '{$foo|auto}', - PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo ($this->config->autoescape ? htmlspecialchars($__Context->foo, ENT_QUOTES, \'UTF-8\', false) : ($__Context->foo)) ?>' + PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo ($this->config->autoescape ? htmlspecialchars($__Context->foo ?? \'\', ENT_QUOTES, \'UTF-8\', false) : ($__Context->foo ?? \'\')) ?>' ), array( '{$foo->$bar|auto}', @@ -352,32 +352,32 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test ), array( '{$foo|autoescape}', - PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo htmlspecialchars($__Context->foo, ENT_QUOTES, \'UTF-8\', false) ?>' + PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo htmlspecialchars($__Context->foo ?? \'\', ENT_QUOTES, \'UTF-8\', false) ?>' ), array( '{$foo|autoescape}', - PHP_EOL . '$this->config->autoescape = false;' . "\n" . 'echo htmlspecialchars($__Context->foo, ENT_QUOTES, \'UTF-8\', false) ?>' + PHP_EOL . '$this->config->autoescape = false;' . "\n" . 'echo htmlspecialchars($__Context->foo ?? \'\', ENT_QUOTES, \'UTF-8\', false) ?>' ), array( '{$foo|escape}', - PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo htmlspecialchars($__Context->foo, ENT_QUOTES, \'UTF-8\', true) ?>' + PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo htmlspecialchars($__Context->foo ?? \'\', ENT_QUOTES, \'UTF-8\', true) ?>' ), array( '{$foo|escape}', - PHP_EOL . '$this->config->autoescape = false;' . "\n" . 'echo htmlspecialchars($__Context->foo, ENT_QUOTES, \'UTF-8\', true) ?>' + PHP_EOL . '$this->config->autoescape = false;' . "\n" . 'echo htmlspecialchars($__Context->foo ?? \'\', ENT_QUOTES, \'UTF-8\', true) ?>' ), array( '{$foo|noescape}', - PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo $__Context->foo ?>' + PHP_EOL . '$this->config->autoescape = true;' . "\n" . 'echo $__Context->foo ?? \'\' ?>' ), array( '{$foo|noescape}', - PHP_EOL . '$this->config->autoescape = false;' . "\n" . 'echo $__Context->foo ?>' + PHP_EOL . '$this->config->autoescape = false;' . "\n" . 'echo $__Context->foo ?? \'\' ?>' ), // Rhymix filters array( '

    {$foo|escape}

    ', - '?>

    foo, ENT_QUOTES, \'UTF-8\', true) ?>

    ' + '?>

    foo ?? \'\', ENT_QUOTES, \'UTF-8\', true) ?>

    ' ), array( '

    {$foo|json}

    ', @@ -445,19 +445,19 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test ), array( '

    {$foo[$bar]|link}

    ', - '?>

    foo[$__Context->bar] . \'">\' . $__Context->foo[$__Context->bar] . \'\' ?>

    ' + '?>

    foo[$__Context->bar]) . \'">\' . ($__Context->foo[$__Context->bar]) . \'\' ?>

    ' ), array( '

    {$foo|link:http://www.rhymix.org}

    ', - '?>

    \' . $__Context->foo . \'\' ?>

    ' + '?>

    \' . ($__Context->foo ?? \'\') . \'\' ?>

    ' ), array( '

    {$foo|link:$url}

    ', - '?>

    url . \'">\' . $__Context->foo . \'\' ?>

    ' + '?>

    url ?? \'\') . \'">\' . ($__Context->foo ?? \'\') . \'\' ?>

    ' ), array( '

    {$foo|link:$url}

    ', - PHP_EOL . '$this->config->autoescape = true; ?>

    config->autoescape ? htmlspecialchars($__Context->url, ENT_QUOTES, \'UTF-8\', false) : ($__Context->url)) . \'">\' . ($this->config->autoescape ? htmlspecialchars($__Context->foo, ENT_QUOTES, \'UTF-8\', false) : ($__Context->foo)) . \'\' ?>

    ' + PHP_EOL . '$this->config->autoescape = true; ?>

    config->autoescape ? htmlspecialchars($__Context->url ?? \'\', ENT_QUOTES, \'UTF-8\', false) : ($__Context->url ?? \'\'))) . \'">\' . (($this->config->autoescape ? htmlspecialchars($__Context->foo ?? \'\', ENT_QUOTES, \'UTF-8\', false) : ($__Context->foo ?? \'\'))) . \'\' ?>

    ' ), // Rhymix filters (reject malformed filters) array( @@ -526,7 +526,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test $result = $tmpl->compileDirect(__DIR__ . '/template', 'sample.html'); $result = trim($result); - $this->assertEquals($result, $this->prefix.PHP_EOL.'if($__Context->has_blog){ ?>Taggon\'s blog'.PHP_EOL.''); + $this->assertEquals($this->prefix.PHP_EOL.'if($__Context->has_blog ?? false){ ?>Taggon\'s blog'.PHP_EOL.'', $result); } }