Details
-
Type:
Improvement
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: 2.0.5
-
Fix Version/s: None
-
Component/s: Drivers
-
Labels:None
Description
SQL statements may contain question marks in strings, inline comments or comment blocks. The current implementation of the method "convertPositionalToNamedPlaceholders()" doesn't consider these implications and falsely replaces them by named bind variables.
Replacement code with example:
<?php $s = '-- Testkomm?ntar select /* ? *//* ??? */ ?||\'H"al?l"o?\' as "h?""llo" union /* "? Kommentar" \' */ /* ?" */ select \'/*Hallo\'||to_char( ? ) union select \'--Welt\' union-- select ?'; echo 'In: ' . $s . PHP_EOL; $bind = 0; $skip = array( '--' => PHP_EOL, '/*' => '*/', '"' => '"', "'" => "'" ); for( $i = 0; $i < strlen( $s ) /* size of string might change! */; /* yes, no increment here! */ ) { // Skipping comments and literals foreach( $skip as $begin => $end ) { $matches = substr_compare( $s, $begin, $i, strlen( $begin ) ); if( $matches !== false && $matches == 0 ) { $pos = strpos( $s, $end, $i+strlen( $begin ) ); // echo "Found $begin, skipping at $i to $end at $pos" . PHP_EOL; if( $pos === false ) { // No more data or illegal statement - anyway: no more replacements! // echo "EOD" . PHP_EOL; break 2; } $i = $pos + strlen( $end ); continue 2; // Ensure we match /*..*//*..*/, '''' or """" - that's why we don't ++$i in the for-loop! } } if( $s[$i] == "?" ) { // Positional to named // echo "Replace $bind" . PHP_EOL; $r = ':name' . ++$bind; $s = substr_replace( $s, $r, $i, 1 ); $i += strlen( $r ); } ++$i; } echo 'Out: ' . $s . PHP_EOL;