mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-19 15:22:17 +02:00
N°5725 - Twig update 'filter', 'map' and 'reduce' filters (+1 squashed commits)
Squashed commits: [00148dec5] N°5725 - Twig update 'filter', 'map' and 'reduce' filters
This commit is contained in:
@@ -100,15 +100,41 @@ class AppExtension extends AbstractExtension
|
|||||||
//since 2.7.7 3.0.2 3.1.0 N°4867 "Twig content not allowed" error when use the extkey widget search icon in the user portal
|
//since 2.7.7 3.0.2 3.1.0 N°4867 "Twig content not allowed" error when use the extkey widget search icon in the user portal
|
||||||
//overwrite native twig filter : disable use of 'system' filter
|
//overwrite native twig filter : disable use of 'system' filter
|
||||||
$filters[] = new Twig_SimpleFilter('filter', function ($array, $arrow) {
|
$filters[] = new Twig_SimpleFilter('filter', function ($array, $arrow) {
|
||||||
if ($arrow == 'system'){
|
$ret = $this->SanitizeFilter($array, $arrow);
|
||||||
return json_encode($array);
|
if ($ret !== false) {
|
||||||
|
return [$ret];
|
||||||
}
|
}
|
||||||
return twig_array_filter($array, $arrow);
|
return twig_array_filter($array, $arrow);
|
||||||
});
|
});
|
||||||
|
$filters[] = new Twig_SimpleFilter('map', function ($array, $arrow) {
|
||||||
|
$ret = $this->SanitizeFilter($array, $arrow);
|
||||||
|
if ($ret !== false) {
|
||||||
|
return [$ret];
|
||||||
|
}
|
||||||
|
return twig_array_map($array, $arrow);
|
||||||
|
});
|
||||||
|
$filters[] = new Twig_SimpleFilter('reduce', function ($array, $arrow, $initial = null) {
|
||||||
|
$ret = $this->SanitizeFilter($array, $arrow);
|
||||||
|
if ($ret !== false) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
// reduce return mixed results not only arrays
|
||||||
|
return twig_array_reduce($array, $arrow, $initial);
|
||||||
|
});
|
||||||
|
|
||||||
return $filters;
|
return $filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function SanitizeFilter($array, $arrow)
|
||||||
|
{
|
||||||
|
if (is_string($arrow)) {
|
||||||
|
if (in_array(strtolower($arrow), ['system', 'exec', 'passthru', 'popen'])) {
|
||||||
|
return json_encode($array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array|\Twig\TwigFunction[]|\Twig_SimpleFunction[]
|
* @return array|\Twig\TwigFunction[]|\Twig_SimpleFunction[]
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ use Combodo\iTop\Portal\Twig\AppExtension;
|
|||||||
use Twig_Environment;
|
use Twig_Environment;
|
||||||
use Twig_Loader_Array;
|
use Twig_Loader_Array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @runTestsInSeparateProcesses
|
||||||
|
* @preserveGlobalState disabled
|
||||||
|
* @backupGlobals disabled
|
||||||
|
*/
|
||||||
class TwigTest extends ItopDataTestCase
|
class TwigTest extends ItopDataTestCase
|
||||||
{
|
{
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
|
|||||||
@@ -1,33 +1,46 @@
|
|||||||
<div>
|
<div>User Name</div>
|
||||||
User Name
|
|
||||||
</div><div>
|
<div>['id']|filter('system')|join</div>
|
||||||
['id']|filter('system')
|
["id"]
|
||||||
</div>
|
|
||||||
["id"]
|
<div>['echo']|filter('passthru')|join</div>
|
||||||
<div>
|
["echo"]
|
||||||
['touch+/tmp/test+']|filter('system')|join(',')
|
|
||||||
</div>
|
<div>['echo']|filter('popen')|join</div>
|
||||||
["touch+\/tmp\/test+"]
|
["echo"]
|
||||||
<div>
|
|
||||||
set sizes = [34, 36, 38, 40, 42]
|
<div>['echo']|filter('exec')|join</div>
|
||||||
sizes|filter(v => v > 38)|join(', ')
|
["echo"]
|
||||||
</div>
|
|
||||||
40, 42
|
<div>['id']|filter('SysteM')|join</div>
|
||||||
<div>
|
["id"]
|
||||||
app.request.server.all|join(',')
|
|
||||||
</div><div>
|
<div>['touch+/tmp/test+']|filter('system')|join(',')</div>
|
||||||
self
|
["touch+\/tmp\/test+"]
|
||||||
</div><div>
|
|
||||||
[0]|reduce('system','echo')
|
<div>[34, 36, 38, 40, 42]|filter(v => v > 38)|join(', ')</div>
|
||||||
</div>
|
40, 42
|
||||||
["echo"]
|
|
||||||
<div>
|
<div>app.request.server.all|join(',')</div>
|
||||||
['echo']|map('system')|join
|
|
||||||
</div>
|
|
||||||
["echo"]
|
<div>self</div>
|
||||||
<div>
|
|
||||||
['echo',1]|sort('system')|join
|
|
||||||
</div>
|
<div>[0]|reduce('system','echo')</div>
|
||||||
echo1
|
[0]
|
||||||
POST /subscribe?0=cat+/etc/passwd HTTP/1.1
|
|
||||||
email=""@attacker.tld
|
<div>[1, 2, 3]|reduce((carry, v) => carry + v)</div>
|
||||||
|
6
|
||||||
|
|
||||||
|
<div>['echo']|map('system')|join</div>
|
||||||
|
["echo"]
|
||||||
|
|
||||||
|
<div>{"Bob": "Smith", "Alice": "Dupond"}|map((value, key) => "#{key} #{value}")|join(', ')</div>
|
||||||
|
Bob Smith, Alice Dupond
|
||||||
|
|
||||||
|
<div>['echo',1]|sort('system')|join</div>
|
||||||
|
echo1
|
||||||
|
|
||||||
|
POST /subscribe?0=cat+/etc/passwd HTTP/1.1
|
||||||
|
email=""@attacker.tld
|
||||||
@@ -1,41 +1,51 @@
|
|||||||
{% spaceless %}
|
<div>{{ 'UI:Login:UserNamePrompt'|dict_s }}</div>
|
||||||
<div>
|
|
||||||
{{ 'UI:Login:UserNamePrompt'|dict_s }}
|
<div>['id']|filter('system')|join</div>
|
||||||
</div>
|
{{ ['id']|filter('system')|join }}
|
||||||
<div>
|
|
||||||
['id']|filter('system')
|
<div>['echo']|filter('passthru')|join</div>
|
||||||
</div>
|
{{ ['echo']|filter('passthru')|join }}
|
||||||
{{ ['id']|filter('system') }}
|
|
||||||
<div>
|
<div>['echo']|filter('popen')|join</div>
|
||||||
['touch+/tmp/test+']|filter('system')|join(',')
|
{{ ['echo']|filter('popen')|join }}
|
||||||
</div>
|
|
||||||
{{ ['touch+/tmp/test+']|filter('system')|join(',') }}
|
<div>['echo']|filter('exec')|join</div>
|
||||||
<div>
|
{{ ['echo']|filter('exec')|join }}
|
||||||
set sizes = [34, 36, 38, 40, 42]
|
|
||||||
sizes|filter(v => v > 38)|join(', ')
|
<div>['id']|filter('SysteM')|join</div>
|
||||||
</div>
|
{{ ['id']|filter('SysteM')|join }}
|
||||||
{% set sizes = [34, 36, 38, 40, 42] %}
|
|
||||||
{{ sizes|filter(v => v > 38)|join(', ') }}
|
<div>['touch+/tmp/test+']|filter('system')|join(',')</div>
|
||||||
<div>
|
{{ ['touch+/tmp/test+']|filter('system')|join(',') }}
|
||||||
app.request.server.all|join(',')
|
|
||||||
</div>
|
<div>[34, 36, 38, 40, 42]|filter(v => v > 38)|join(', ')</div>
|
||||||
{{ app.request.server.all|join(',') }} {# needs syfony #}
|
{{ [34, 36, 38, 40, 42]|filter(v => v > 38)|join(', ') }}
|
||||||
<div>
|
|
||||||
self
|
<div>app.request.server.all|join(',')</div>
|
||||||
</div>
|
{{ app.request.server.all|join(',')}}
|
||||||
{{ self }} {# ??? not sure #}
|
|
||||||
<div>
|
<div>self</div>
|
||||||
[0]|reduce('system','echo')
|
{{ self }}
|
||||||
</div>
|
|
||||||
{{ [0]|reduce('system','echo') }}
|
<div>[0]|reduce('system','echo')</div>
|
||||||
<div>
|
{{ [0]|reduce('system','echo') }}
|
||||||
['echo']|map('system')|join
|
|
||||||
</div>
|
<div>[1, 2, 3]|reduce((carry, v) => carry + v)</div>
|
||||||
{{ ['echo']|map('system')|join }}
|
{% set numbers = [1, 2, 3] %}
|
||||||
<div>
|
{{ numbers|reduce((carry, v) => carry + v) }}
|
||||||
['echo',1]|sort('system')|join
|
|
||||||
</div>
|
<div>['echo']|map('system')|join</div>
|
||||||
{{ ['echo',1]|sort('system')|join }}
|
{{ ['echo']|map('system')|join }}
|
||||||
POST /subscribe?0=cat+/etc/passwd HTTP/1.1
|
|
||||||
email="{{ app.request.query.filter(0,0,1024,{'options':'system'}) }}"@attacker.tld
|
<div>{"Bob": "Smith", "Alice": "Dupond"}|map((value, key) => "#{key} #{value}")|join(', ')</div>
|
||||||
{% endspaceless %}
|
{% set people = {
|
||||||
|
"Bob": "Smith",
|
||||||
|
"Alice": "Dupond",
|
||||||
|
} %}
|
||||||
|
{{ people|map((value, key) => "#{key} #{value}")|join(', ') }}
|
||||||
|
|
||||||
|
<div>['echo',1]|sort('system')|join</div>
|
||||||
|
{{ ['echo',1]|sort('system')|join }}
|
||||||
|
|
||||||
|
POST /subscribe?0=cat+/etc/passwd HTTP/1.1
|
||||||
|
email="{{ app.request.query.filter(0,0,1024,{'options':'system'}) }}"@attacker.tld
|
||||||
Reference in New Issue
Block a user