Dbal: Doctrine\DBAL\Schema\SqliteSchemaManager: "preg_match(): Compilation failed: missing ) at offset 163"

Created on 6 Oct 2017  路  5Comments  路  Source: doctrine/dbal

Hi,

I'm using Symfony with the LiipFunctionalTestBundle to mock my database and create a local sqlite database mock.

Used bundles:

  • doctrine/doctrine-bundle: v1.6.3
  • doctrine/dbal: v2.5.4

One of my entitie's column name is FOO# (legacy database), which causes strange errors in https://github.com/doctrine/dbal/blob/v2.6.2/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php#L465.

Error:
preg_match(): Compilation failed: missing ) at offset 163

Seems the regex is missing a delimiter. Wrapping the regex into / fixes my issue.

Fixed code:

private function parseColumnCollationFromSQL($column, $sql)
    {
        if (preg_match(
            '/{(?:'.preg_quote($column).'|'.preg_quote($this->_platform->quoteSingleIdentifier($column)).')
            [^,(]+(?:\([^()]+\)[^,]*)?
            (?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*
            COLLATE\s+["\']?([^\s,"\')]+)}isx/', $sql, $match)) {
            return $match[1];
        }

        return false;
    }

Entity:

class Dummy {
  /**
   * @ORM\Column(name="`FOO#`, type=string)
   */
  private $foo;
}
Bug Schema Introspection Schema Managers

All 5 comments

@Bruce17 the original expression has { and } as delimiters. The version you provided puts the isx flags inside the regex body which changes its logic.

I believe the problem is that the calls to preg_quote() don't have the second parameter passed, and special characters in the column name get escaped in an unexpected way.

Could you create a pull request first so that the patch could be automatically tested? Also, there should be a functional test which creates a table with the column in question and calls SqliteSchemaManager::listTableColumns() on the schema. I believe this is the lowest possible level to test this regex.

Seems that # is also a special character in php regex, but gets not escaped by preg_quote directly. I added it as second parameter to it to fix this issue.

I prepared a pull request including a fix and updated the unit tests.

Seems that # is also a special character in php regex, but gets not escaped by preg_quote directly.

I reported this to PHP directly as this is something it should be taken care of by PCRE itself.
https://bugs.php.net/bug.php?id=75355

Can we get rid of the /x modifier in expressions so that the # doesn't get interpreted as a comment start? The approach of passing a made up modifier still looks hacky.

PR submitted to php-src: https://github.com/php/php-src/pull/2838

Can we get rid of the /x modifier in expressions so that the # doesn't get interpreted as a comment start?

That would be also an option, it's there only for better readability.

Was this page helpful?
0 / 5 - 0 ratings