Index: class.tslib_content.php =================================================================== --- class.tslib_content.php (revision 7199) +++ class.tslib_content.php (working copy) @@ -7609,6 +7609,9 @@ */ function getQuery($table, $conf, $returnQueryArray=FALSE) { + // Handle PDO-style named parameter markers first + $this->insertQueryMarkers($table, $conf); + // Construct WHERE clause: $conf['pidInList'] = trim($this->stdWrap($conf['pidInList'],$conf['pidInList.'])); @@ -7837,6 +7840,81 @@ return $this->checkPid_cache[$uid]; } + /** + * Handles PDO-like parameter markers in select parts. + * Enables the use of all stdWrap functionality in various properties AND prevents SQL-injection problems by quoting and escaping + * of numeric values, strings and lists + * + * @param string $table Table to select records from + * @param array $conf Select part of CONTENT definition + * @access private + * @see getQuery() + */ + function insertQueryMarkers($table, &$conf) { + if (is_array($conf['markers.'])) { + // parse markers and prepare their values + $markerValues = array(); + // TODO: provide function in core to add keys without dot suffix when key with dot suffix exists. + foreach($conf['markers.'] as $marker => $dummy) { + if (strpos($marker, '.') !== FALSE && !isset ($conf['markers.'][substr($marker, 0, -1)])) { + $conf['markers.'][substr($marker, 0, -1)] = ''; + } + } + foreach($conf['markers.'] as $marker => $dummy) { + if (strpos($marker, '.') === FALSE) { + // parse definition + $tempValue = $this->stdWrap($conf['markers.'][$marker], $conf['markers.'][$marker . '.']); + // quote/escape if needed + if (is_numeric($tempValue)) { + if ((int)$tempValue == $tempValue) { + // handle integer + $markerValues[$marker] = intval($tempValue); + } else { + // handle float + $markerValues[$marker] = floatval($tempValue); + } + } else { + // see if it is a comma separated list of values + $explodeValues = t3lib_div::trimExplode(',', $tempValue); + if (count($explodeValues) > 1) { + // handle each element of list separately + $tempArray = array(); + foreach ($explodeValues as $listValue) { + if (is_numeric($listValue)) { + if ((int)$listValue == $listValue) { + $tempArray[] = intval($listValue); + } else { + $tempArray[] = floatval($listValue); + } + } else { + // if quoted, remove quotes before escaping. + if (preg_match('/^\'([^\']*)\'$/', $listValue, $matches)) { + $listValue = $matches[1]; + } elseif (preg_match('/^\"([^\"]*)\"$/', $listValue, $matches)) { + $listValue = $matches[1]; + } + $tempArray[] = $GLOBALS['TYPO3_DB']->fullQuoteStr($listValue, $table); + } + } + $markerValues[$marker] = implode(',', $tempArray); + } else { + // handle remaining values as string + $markerValues[$marker] = $GLOBALS['TYPO3_DB']->fullQuoteStr($tempValue, $table); + } + } + } + } + // replace the markers in various parts of the select configuration + foreach ($markerValues as $marker => $markerValue) { + $properties = array('uidInList', 'selectFields', 'pidInList', 'where', 'max', 'begin', 'groupBy', 'orderBy', 'join', 'leftjoin', 'rightjoin'); + foreach ($properties as $property) { + if ($conf[$property]) { + $conf[$property] = preg_replace('/###' . preg_quote($marker) . '###/', $markerValue, $conf[$property]); + } + } + } + } + } @@ -7862,6 +7940,7 @@ + /*********************************************** * * Frontend editing functions