Commit 3d546c80 authored by Victor Costan's avatar Victor Costan Committed by Commit Bot

websql: Fix racy SQLite API usage in SQLiteStatement.

SQLiteStatement::GetColumn value currently uses sqlite3_column_value()
to retrieve a sqlite3_value*, and then uses other API calls to extract
information from the value.

The SQLite documentation [1, 2] states that sqlite3_column_value()
returns an "unprotected value", which should not be operated on
directly. When SQLite is compiled with multi-threading support (as
Chrome does), the incorrect usage triggers assets in SQLite.

This CL replaces the incorrect usage of sqlite3_value* with SQLite API
calls documented in [2] which are safe to use, inspired from
sql::Statement.

[1] https://www.sqlite.org/c3ref/value.html
[2] https://www.sqlite.org/c3ref/column_blob.html

Bug: 906396
Change-Id: Ic8f7caac31c5be91113af576c020236aeb4106dc
Reviewed-on: https://chromium-review.googlesource.com/c/1343574
Commit-Queue: Victor Costan <pwnall@chromium.org>
Reviewed-by: default avatarJoshua Bell <jsbell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609748}
parent 87a698ee
...@@ -254,24 +254,21 @@ SQLValue SQLiteStatement::GetColumnValue(int col) { ...@@ -254,24 +254,21 @@ SQLValue SQLiteStatement::GetColumnValue(int col) {
// SQLite is typed per value. optional column types are // SQLite is typed per value. optional column types are
// "(mostly) ignored" // "(mostly) ignored"
sqlite3_value* value = sqlite3_column_value(statement_, col); switch (sqlite3_column_type(statement_, col)) {
switch (sqlite3_value_type(value)) {
case SQLITE_INTEGER: // SQLValue and JS don't represent integers, so use case SQLITE_INTEGER: // SQLValue and JS don't represent integers, so use
// FLOAT -case // FLOAT -case
case SQLITE_FLOAT: case SQLITE_FLOAT:
return SQLValue(sqlite3_value_double(value)); return SQLValue(sqlite3_column_double(statement_, col));
case SQLITE_BLOB: // SQLValue and JS don't represent blobs, so use TEXT case SQLITE_BLOB: // SQLValue and JS don't represent blobs, so use TEXT
// -case // -case
case SQLITE_TEXT: { case SQLITE_TEXT: {
const UChar* string = const UChar* string = reinterpret_cast<const UChar*>(
reinterpret_cast<const UChar*>(sqlite3_value_text16(value)); sqlite3_column_text16(statement_, col));
unsigned length = sqlite3_value_bytes16(value) / sizeof(UChar); unsigned length = sqlite3_column_bytes16(statement_, col) / sizeof(UChar);
return SQLValue(StringImpl::Create8BitIfPossible(string, length)); return SQLValue(StringImpl::Create8BitIfPossible(string, length));
} }
case SQLITE_NULL: case SQLITE_NULL:
return SQLValue(); return SQLValue();
default:
break;
} }
NOTREACHED(); NOTREACHED();
return SQLValue(); return SQLValue();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment