Unverified Commit 635b4228 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3133798 by Beakerboy, daffie: Semicolon removed from query even when it is allowed

parent 4a0c41de
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -628,7 +628,11 @@ public function query($query, array $args = [], $options = []) {
        // semicolons should only be needed for special cases like defining a
        // function or stored procedure in SQL. Trim any trailing delimiter to
        // minimize false positives.
        $query = rtrim($query, ";  \t\n\r\0\x0B");
        $trim_chars = "  \t\n\r\0\x0B";
        if (empty($options['allow_delimiter_in_query'])) {
          $trim_chars .= ';';
        }
        $query = rtrim($query, $trim_chars);
        if (strpos($query, ';') !== FALSE && empty($options['allow_delimiter_in_query'])) {
          throw new \InvalidArgumentException('; is not supported in SQL strings. Use only one statement at a time.');
        }
+55 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
namespace Drupal\Tests\Core\Database;

use Drupal\Tests\Core\Database\Stub\StubConnection;
use Drupal\Tests\Core\Database\Stub\StubPDO;
use Drupal\Tests\UnitTestCase;

/**
@@ -297,4 +298,58 @@ public function testFilterComments($expected, $comment) {
    );
  }

  /**
   * Test rtrim() of query strings.
   *
   * @dataProvider provideQueriesToTrim
   */
  public function testQueryTrim($expected, $query, $options) {
    $mock_pdo = $this->getMockBuilder(StubPdo::class)
      ->setMethods(['execute', 'prepare', 'setAttribute'])
      ->getMock();

    // Ensure that PDO::prepare() is called only once, and with the
    // correctly trimmed query string.
    $mock_pdo->expects($this->once())
      ->method('prepare')
      ->with($expected)
      ->willReturnSelf();
    $connection = new StubConnection($mock_pdo, []);
    $connection->query($query, [], $options);
  }

  /**
   * Dataprovider for testQueryTrim().
   *
   * @return array
   *   Array of arrays with the following elements:
   *   - Expected trimmed query.
   *   - Padded query.
   *   - Query options.
   */
  public function provideQueriesToTrim() {
    return [
      'remove_semicolon' => [
        'SELECT * FROM test',
        'SELECT * FROM test;',
        [],
      ],
      'keep_trailing_semicolon' => [
        'SELECT * FROM test;',
        'SELECT * FROM test;',
        ['allow_delimiter_in_query' => TRUE],
      ],
      'remove_semicolon_with_whitespace' => [
        'SELECT * FROM test',
        'SELECT * FROM test; ',
        [],
      ],
      'keep_trailing_semicolon_with_whitespace' => [
        'SELECT * FROM test;',
        'SELECT * FROM test; ',
        ['allow_delimiter_in_query' => TRUE],
      ],
    ];
  }

}