Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
typo3
qfq
Commits
ee6ad621
Commit
ee6ad621
authored
May 30, 2016
by
Carsten Rose
Browse files
Evalulate.php: user can optional define that single or double ticks in replaced token are escaped.
parent
ee5044e8
Changes
3
Show whitespace changes
Inline
Side-by-side
extension/qfq/qfq/Constants.php
View file @
ee6ad621
...
...
@@ -313,6 +313,10 @@ const SIP_URLPARAM = 'urlparam';
const
VAR_RANDOM
=
'random'
;
// TOKEN evaluate
const
TOKEN_ESCAPE_SINGLE_TICK
=
's'
;
const
TOKEN_ESCAPE_DOUBLE_TICK
=
'd'
;
const
TOKEN_FOUND_IN_STORE_QUERY
=
'query'
;
const
RANDOM_LENGTH
=
32
;
...
...
@@ -434,6 +438,7 @@ const FE_PATH_FILE_NAME = 'pathFileName'; // Target pathFilename for an uploaded
const
FE_SQL_VALIDATE
=
'sqlValidate'
;
// Action: Query to validate form load
const
FE_EXPECT_RECORDS
=
'expectRecords'
;
// Action: expected number of rows of FE_SQL_VALIDATE
const
FE_MESSAGE_FAIL
=
'messageFail'
;
// Action: Message to display, if FE_SQL_VALIDATE fails.
const
FE_REQUIRED_LIST
=
'requiredList'
;
// Optional list of FormElements which have to be non empty to make this 'action'-FormElement active.
const
FE_SLAVE_ID
=
'slaveId'
;
// Action; Value or Query to compute id of slave record.
const
FE_SQL_UPDATE
=
'sqlUpdate'
;
// Action: Update Statement for slave record
const
FE_SQL_INSERT
=
'sqlInsert'
;
// Action: Insert Statement to create slave record.
...
...
extension/qfq/qfq/Evaluate.php
View file @
ee6ad621
...
...
@@ -147,15 +147,16 @@ class Evaluate {
/**
* Tries to substitute $token.
* Token might be
* Token might be
:
* a) a SQL statement to fire
* b) fetch from a store. Syntax: 'form', 'form:C', 'form:SC0', 'form:S:ALNUMX'
* b) fetch from a store. Syntax: 'form', 'form:C', 'form:SC0', 'form:S:alnumx', 'form:F:all:s'
*
* The token have to be _without_ Delimiter '{{' / '}}'
* If neither a) or b) match, return the token itself
, surrounded by single ticks, to emphase that substition failed
.
* If neither a) or b) match, return the token itself.
*
* @param $token
* @param string $foundInStore Returns the name of the store where $key has been found. If $key is not found, return ''.
* @return array|
mixed|
null|string
* @return array|null|string
* @throws CodeException
* @throws DbException
*/
...
...
@@ -175,21 +176,31 @@ class Evaluate {
// SQL Statement?
if
(
in_array
(
strtoupper
(
$arr
[
0
]
.
' '
),
$this
->
sqlKeywords
))
{
$foundInStore
=
'query'
;
$foundInStore
=
TOKEN_FOUND_IN_STORE_QUERY
;
return
$this
->
db
->
sql
(
$token
,
$sqlMode
);
}
// explode for: <key>:<store priority>:<sanitize class>
$arr
=
explode
(
':'
,
$token
,
3
);
if
(
!
isset
(
$arr
[
1
]))
$arr
[
1
]
=
null
;
if
(
!
isset
(
$arr
[
2
]))
$arr
[
2
]
=
null
;
// explode for: <key>:<store priority>:<sanitize class>:<escape>
$arr
=
explode
(
':'
,
$token
,
4
);
$arr
=
array_merge
(
$arr
,
[
null
,
null
,
null
,
null
]);
// fake isset()
// search for value in stores
$value
=
$this
->
store
->
getVar
(
$arr
[
0
],
$arr
[
1
],
$arr
[
2
],
$foundInStore
);
// escape ticks
if
(
is_string
(
$value
))
{
switch
(
$arr
[
3
])
{
case
TOKEN_ESCAPE_SINGLE_TICK
:
$value
=
str_replace
(
"'"
,
"
\\
'"
,
$value
);
break
;
case
TOKEN_ESCAPE_DOUBLE_TICK
:
$value
=
str_replace
(
'"'
,
'\\"'
,
$value
);
break
;
default
:
break
;
}
}
// OLD: nothing replaced: put ticks around, to sanitize strings for SQL statements. Nothing to substitute is not a wished situation.
// return ($value === false) ? "'" . $token . "'" : $value;
...
...
extension/qfq/tests/phpunit/EvaluateTest.php
View file @
ee6ad621
...
...
@@ -100,7 +100,6 @@ class EvaluateTest extends \AbstractDatabaseTest {
$this
->
store
->
setVar
(
'a'
,
'{{b:C:all}}'
,
'C'
);
$this
->
store
->
setVar
(
'b'
,
'Holiday'
,
'C'
);
$this
->
assertEquals
(
'Holiday'
,
$eval
->
parse
(
'{{SELECT name FROM Person WHERE name=\'{{a:C:all}}\'}}'
));
}
public
function
testParseArray
()
{
...
...
@@ -116,8 +115,6 @@ class EvaluateTest extends \AbstractDatabaseTest {
];
$this
->
assertEquals
(
$expected
,
$eval
->
parseArray
(
$data
));
}
public
function
testParseArrayOfArray
()
{
...
...
@@ -146,6 +143,173 @@ class EvaluateTest extends \AbstractDatabaseTest {
$this
->
assertEquals
(
$expected
,
$eval
->
parseArray
(
$data
));
}
public
function
testSubstituteSql
()
{
$eval
=
new
\
qfq\Evaluate
(
$this
->
store
,
$this
->
db
);
$expectArr
=
[
0
=>
[
'name'
=>
'Holiday'
,
'firstname'
=>
'Billie'
],
1
=>
[
'name'
=>
'Holiday'
,
'firstname'
=>
'Billie'
]];
$eval
->
parse
(
'{{INSERT INTO Person (name, firstname) VALUES (\'Holiday\', \'Billie\')}}'
);
$eval
->
parse
(
'{{INSERT INTO Person (name, firstname) VALUES (\'Holiday\', \'Billie\')}}'
);
$this
->
store
->
setVar
(
'a'
,
'{{b:C:all}}'
,
'C'
);
$this
->
store
->
setVar
(
'b'
,
'Holiday'
,
'C'
);
// Fire query: empty
$this
->
assertEquals
(
''
,
$eval
->
substitute
(
'SELECT name FROM Person WHERE id=0'
,
$foundInStore
));
$this
->
assertEquals
(
TOKEN_FOUND_IN_STORE_QUERY
,
$foundInStore
);
// Fire query
$this
->
assertEquals
(
'Holiday'
,
$eval
->
substitute
(
'SELECT name FROM Person WHERE name LIKE "Holiday" LIMIT 1'
,
$foundInStore
));
$this
->
assertEquals
(
TOKEN_FOUND_IN_STORE_QUERY
,
$foundInStore
);
// Fire query, surrounding whitespace
$this
->
assertEquals
(
'Holiday'
,
$eval
->
substitute
(
' SELECT name FROM Person WHERE name LIKE "Holiday" LIMIT 1 '
,
$foundInStore
));
$this
->
assertEquals
(
TOKEN_FOUND_IN_STORE_QUERY
,
$foundInStore
);
// Fire query, lowercase
$this
->
assertEquals
(
'Holiday'
,
$eval
->
substitute
(
' SELECT name FROM Person WHERE name LIKE "Holiday" LIMIT 1'
,
$foundInStore
));
$this
->
assertEquals
(
TOKEN_FOUND_IN_STORE_QUERY
,
$foundInStore
);
// Fire query, join two records
$this
->
assertEquals
(
'HolidayBillieHolidayBillie'
,
$eval
->
substitute
(
'SELECT name, firstname FROM Person WHERE name LIKE "Holiday" LIMIT 2'
,
$foundInStore
));
$this
->
assertEquals
(
TOKEN_FOUND_IN_STORE_QUERY
,
$foundInStore
);
// Fire query, two records as assoc
$this
->
assertEquals
(
$expectArr
,
$eval
->
substitute
(
'!SELECT name, firstname FROM Person WHERE name LIKE "Holiday" LIMIT 2'
,
$foundInStore
));
$this
->
assertEquals
(
TOKEN_FOUND_IN_STORE_QUERY
,
$foundInStore
);
// Fire query, no result
$this
->
assertEquals
(
array
(),
$eval
->
substitute
(
'!SELECT name, firstname FROM Person WHERE id=0'
,
$foundInStore
));
$this
->
assertEquals
(
TOKEN_FOUND_IN_STORE_QUERY
,
$foundInStore
);
// Fire query, two records as assoc, surrounding whitespace
$this
->
assertEquals
(
$expectArr
,
$eval
->
substitute
(
' !select name, firstname FROM Person WHERE name LIKE "Holiday" LIMIT 2 '
,
$foundInStore
));
$this
->
assertEquals
(
TOKEN_FOUND_IN_STORE_QUERY
,
$foundInStore
);
}
public
function
testSubstituteVar
()
{
$eval
=
new
\
qfq\Evaluate
(
$this
->
store
,
$this
->
db
);
// Retrieve in PRIO `FSRD`
$this
->
store
->
setVar
(
'a'
,
'1234'
,
STORE_TABLE_DEFAULT
,
true
);
$this
->
assertEquals
(
'1234'
,
$eval
->
substitute
(
'a'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_TABLE_DEFAULT
,
$foundInStore
);
$this
->
store
->
setVar
(
'a'
,
'12345'
,
STORE_RECORD
,
true
);
$this
->
assertEquals
(
'12345'
,
$eval
->
substitute
(
'a'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_RECORD
,
$foundInStore
);
$this
->
store
->
setVar
(
'a'
,
'123456'
,
STORE_SIP
,
true
);
$this
->
assertEquals
(
'123456'
,
$eval
->
substitute
(
'a'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_SIP
,
$foundInStore
);
$this
->
store
->
setVar
(
'a'
,
'1234567'
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
'1234567'
,
$eval
->
substitute
(
'a'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
$this
->
assertEquals
(
false
,
$eval
->
substitute
(
'notFound'
,
$foundInStore
));
$this
->
assertEquals
(
''
,
$foundInStore
);
// Specific Store
$this
->
assertEquals
(
'1234'
,
$eval
->
substitute
(
'a:D'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_TABLE_DEFAULT
,
$foundInStore
);
$this
->
assertEquals
(
'12345'
,
$eval
->
substitute
(
'a:R'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_RECORD
,
$foundInStore
);
$this
->
assertEquals
(
'123456'
,
$eval
->
substitute
(
'a:S'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_SIP
,
$foundInStore
);
$this
->
assertEquals
(
'1234567'
,
$eval
->
substitute
(
'a:F'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
$this
->
assertEquals
(
false
,
$eval
->
substitute
(
'a:V'
,
$foundInStore
));
$this
->
assertEquals
(
''
,
$foundInStore
);
// Sanatize Class: digits
$this
->
assertEquals
(
'1234567'
,
$eval
->
substitute
(
'a:F:digit'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
$this
->
assertEquals
(
'1234567'
,
$eval
->
substitute
(
'a:F:alnumx'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
$this
->
assertEquals
(
'1234567'
,
$eval
->
substitute
(
'a:F:allbut'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
$this
->
assertEquals
(
'1234567'
,
$eval
->
substitute
(
'a:F:all'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
// Sanatize Class: text
$this
->
store
->
setVar
(
'a'
,
'Hello world @-_.,;: /()'
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
''
,
$eval
->
substitute
(
'a:F:digit'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
$this
->
assertEquals
(
'Hello world @-_.,;: /()'
,
$eval
->
substitute
(
'a:F:alnumx'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
$this
->
assertEquals
(
'Hello world @-_.,;: /()'
,
$eval
->
substitute
(
'a:F:allbut'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
$this
->
assertEquals
(
'Hello world @-_.,;: /()'
,
$eval
->
substitute
(
'a:F:all'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
}
public
function
testSubstituteVarEscape
()
{
$eval
=
new
\
qfq\Evaluate
(
$this
->
store
,
$this
->
db
);
// No escape
$this
->
store
->
setVar
(
'a'
,
'hello'
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
'hello'
,
$eval
->
substitute
(
'a:F:all'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
// None, Single Tick
$this
->
store
->
setVar
(
'a'
,
'hello'
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
'hello'
,
$eval
->
substitute
(
'a:F:all:s'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
// None, Double Tick
$this
->
store
->
setVar
(
'a'
,
'hello'
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
'hello'
,
$eval
->
substitute
(
'a:F:all:d'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
// ', Single Tick
$this
->
store
->
setVar
(
'a'
,
'hel\'lo'
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
'hel\\\'lo'
,
$eval
->
substitute
(
'a:F:all:s'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
// ' Double Tick
$this
->
store
->
setVar
(
'a'
,
'hel\'lo'
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
'hel\'lo'
,
$eval
->
substitute
(
'a:F:all:d'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
// ", Single Tick
$this
->
store
->
setVar
(
'a'
,
'hel"lo'
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
'hel"lo'
,
$eval
->
substitute
(
'a:F:all:s'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
// ", Double Tick
$this
->
store
->
setVar
(
'a'
,
'hel"lo'
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
'hel\"lo'
,
$eval
->
substitute
(
'a:F:all:d'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
// Multi ', Single Tick
$this
->
store
->
setVar
(
'a'
,
"h
\"
e' 'l
\"
lo ' "
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
"h
\"
e\' \'l
\"
lo \' "
,
$eval
->
substitute
(
'a:F:all:s'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
// Multi , Double Tick
$this
->
store
->
setVar
(
'a'
,
'h"e\' \'l"lo \' '
,
STORE_FORM
,
true
);
$this
->
assertEquals
(
'h\"e\' \'l\"lo \' '
,
$eval
->
substitute
(
'a:F:all:d'
,
$foundInStore
));
$this
->
assertEquals
(
STORE_FORM
,
$foundInStore
);
}
protected
function
setUp
()
{
$this
->
store
=
Store
::
getInstance
(
'form=TestFormName'
,
true
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment