Skip to content

Commit

Permalink
MDL-59635 tool_replace: Escape the column name.
Browse files Browse the repository at this point in the history
  • Loading branch information
scara committed Sep 4, 2017
1 parent 596f4e6 commit ea34d02
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
3 changes: 2 additions & 1 deletion lib/dml/moodle_database.php
Original file line number Diff line number Diff line change
Expand Up @@ -2398,7 +2398,8 @@ public function replace_all_text($table, database_column_info $column, $search,
// NOTE: override this methods if following standard compliant SQL
// does not work for your driver.

$columnname = $column->name;
// Enclose the column name by the proper quotes if it's a reserved word.
$columnname = $this->get_manager()->generator->getEncQuoted($column->name);
$sql = "UPDATE {".$table."}
SET $columnname = REPLACE($columnname, ?, ?)
WHERE $columnname IS NOT NULL";
Expand Down
46 changes: 41 additions & 5 deletions lib/dml/tests/dml_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -4573,19 +4573,55 @@ public function test_replace_all_text() {
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('name', XMLDB_TYPE_CHAR, '20', null, null);
$table->add_field('intro', XMLDB_TYPE_TEXT, 'big', null, null);
// Add a CHAR field named using a word reserved for all the supported DB servers.
$table->add_field('where', XMLDB_TYPE_CHAR, '20', null, null, null, 'localhost');
// Add a TEXT field named using a word reserved for all the supported DB servers.
$table->add_field('from', XMLDB_TYPE_TEXT, 'big', null, null);
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$dbman->create_table($table);

$id1 = (string)$DB->insert_record($tablename, array('name' => null, 'intro' => null));
$id2 = (string)$DB->insert_record($tablename, array('name' => '', 'intro' => ''));
$id3 = (string)$DB->insert_record($tablename, array('name' => 'xxyy', 'intro' => 'vvzz'));
$id4 = (string)$DB->insert_record($tablename, array('name' => 'aa bb aa bb', 'intro' => 'cc dd cc aa'));
$id5 = (string)$DB->insert_record($tablename, array('name' => 'kkllll', 'intro' => 'kkllll'));
$fromfield = $dbman->generator->getEncQuoted('from');
$DB->execute("INSERT INTO {".$tablename."} (name,intro,$fromfield) VALUES (NULL,NULL,'localhost')");
$DB->execute("INSERT INTO {".$tablename."} (name,intro,$fromfield) VALUES ('','','localhost')");
$DB->execute("INSERT INTO {".$tablename."} (name,intro,$fromfield) VALUES ('xxyy','vvzz','localhost')");
$DB->execute("INSERT INTO {".$tablename."} (name,intro,$fromfield) VALUES ('aa bb aa bb','cc dd cc aa','localhost')");
$DB->execute("INSERT INTO {".$tablename."} (name,intro,$fromfield) VALUES ('kkllll','kkllll','localhost')");

$expected = $DB->get_records($tablename, array(), 'id ASC');
$idx = 1;
$id1 = $id2 = $id3 = $id4 = $id5 = 0;
foreach (array_keys($expected) as $identifier) {
${"id$idx"} = (string)$identifier;
$idx++;
}

$columns = $DB->get_columns($tablename);

// Replace should work even with columns named using a reserved word.
$this->assertEquals('C', $columns['where']->meta_type);
$this->assertEquals('localhost', $expected[$id1]->where);
$this->assertEquals('localhost', $expected[$id2]->where);
$this->assertEquals('localhost', $expected[$id3]->where);
$this->assertEquals('localhost', $expected[$id4]->where);
$this->assertEquals('localhost', $expected[$id5]->where);
$DB->replace_all_text($tablename, $columns['where'], 'localhost', '::1');
$result = $DB->get_records($tablename, array(), 'id ASC');
$expected[$id1]->where = '::1';
$expected[$id2]->where = '::1';
$expected[$id3]->where = '::1';
$expected[$id4]->where = '::1';
$expected[$id5]->where = '::1';
$this->assertEquals($expected, $result);
$this->assertEquals('X', $columns['from']->meta_type);
$DB->replace_all_text($tablename, $columns['from'], 'localhost', '127.0.0.1');
$result = $DB->get_records($tablename, array(), 'id ASC');
$expected[$id1]->from = '127.0.0.1';
$expected[$id2]->from = '127.0.0.1';
$expected[$id3]->from = '127.0.0.1';
$expected[$id4]->from = '127.0.0.1';
$expected[$id5]->from = '127.0.0.1';
$this->assertEquals($expected, $result);

$DB->replace_all_text($tablename, $columns['name'], 'aa', 'o');
$result = $DB->get_records($tablename, array(), 'id ASC');
$expected[$id4]->name = 'o bb o bb';
Expand Down

0 comments on commit ea34d02

Please sign in to comment.