From 553f7da5f9dce8c02fc254d6a1bad958a49e4a98 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sun, 16 May 2010 22:06:29 +0200 Subject: [PATCH] implemented PCRE error checking and PcreException --- dibi/dibi.php | 19 +++++++++++++++++++ dibi/drivers/mysql.php | 2 ++ dibi/drivers/mysqli.php | 2 ++ dibi/libs/DibiTranslator.php | 10 +++++----- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/dibi/dibi.php b/dibi/dibi.php index 2f5a3af0..81586848 100644 --- a/dibi/dibi.php +++ b/dibi/dibi.php @@ -62,6 +62,25 @@ if (!class_exists('FileNotFoundException', FALSE)) { class FileNotFoundException extends IOException {} } +if (!class_exists('PcreException', FALSE)) { + /** @package exceptions */ + class PcreException extends Exception { + + public function __construct() + { + static $messages = array( + PREG_INTERNAL_ERROR => 'Internal error.', + PREG_BACKTRACK_LIMIT_ERROR => 'Backtrack limit was exhausted.', + PREG_RECURSION_LIMIT_ERROR => 'Recursion limit was exhausted.', + PREG_BAD_UTF8_ERROR => 'Malformed UTF-8 data.', + 5 => 'Offset didn\'t correspond to the begin of a valid UTF-8 code point.', // PREG_BAD_UTF8_OFFSET_ERROR + ); + $code = preg_last_error(); + parent::__construct(isset($messages[$code]) ? $messages[$code] : 'Unknown error.', $code); + } + } +} + if (!interface_exists(/*Nette\*/'IDebugPanel', FALSE)) { require_once dirname(__FILE__) . '/Nette/IDebugPanel.php'; } diff --git a/dibi/drivers/mysql.php b/dibi/drivers/mysql.php index 46e631b8..dc1a7f1c 100644 --- a/dibi/drivers/mysql.php +++ b/dibi/drivers/mysql.php @@ -175,6 +175,8 @@ class DibiMySqlDriver extends DibiObject implements IDibiDriver { $res = array(); preg_match_all('#(.+?): +(\d+) *#', mysql_info($this->connection), $matches, PREG_SET_ORDER); + if (preg_last_error()) throw new PcreException; + foreach ($matches as $m) { $res[$m[1]] = (int) $m[2]; } diff --git a/dibi/drivers/mysqli.php b/dibi/drivers/mysqli.php index bd3757ba..7561479d 100644 --- a/dibi/drivers/mysqli.php +++ b/dibi/drivers/mysqli.php @@ -159,6 +159,8 @@ class DibiMySqliDriver extends DibiObject implements IDibiDriver { $res = array(); preg_match_all('#(.+?): +(\d+) *#', mysqli_info($this->connection), $matches, PREG_SET_ORDER); + if (preg_last_error()) throw new PcreException; + foreach ($matches as $m) { $res[$m[1]] = (int) $m[2]; } diff --git a/dibi/libs/DibiTranslator.php b/dibi/libs/DibiTranslator.php index 67ff3d9a..645cc7d5 100644 --- a/dibi/libs/DibiTranslator.php +++ b/dibi/libs/DibiTranslator.php @@ -124,7 +124,7 @@ final class DibiTranslator extends DibiObject array($this, 'cb'), substr($arg, $toSkip) ); - + if (preg_last_error()) throw new PcreException; } continue; } @@ -381,16 +381,16 @@ final class DibiTranslator extends DibiObject $value = (string) $value; // speed-up - is regexp required? $toSkip = strcspn($value, '`[\'":'); - if (strlen($value) === $toSkip) { // needn't be translated - return $value; - } else { - return substr($value, 0, $toSkip) + if (strlen($value) !== $toSkip) { + $value = substr($value, 0, $toSkip) . preg_replace_callback( '/(?=[`[\'":])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)([a-zA-Z0-9._]?))/s', array($this, 'cb'), substr($value, $toSkip) ); + if (preg_last_error()) throw new PcreException; } + return $value; case 'SQL': // preserve as real SQL (TODO: rename to %sql) return (string) $value;