diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-24 02:13:05 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-24 02:13:05 +0000 |
commit | 3f691cf67fee47025e911397e1de3bbed722e4e1 (patch) | |
tree | b7b61f2146273198207545242971bc4fffb7f63b /third_party/sqlite | |
parent | 5f5fca52104ad85aeb4e8a3e64e2a2950fb6bae4 (diff) | |
download | chromium_src-3f691cf67fee47025e911397e1de3bbed722e4e1.zip chromium_src-3f691cf67fee47025e911397e1de3bbed722e4e1.tar.gz chromium_src-3f691cf67fee47025e911397e1de3bbed722e4e1.tar.bz2 |
Handle UTF16 encodings in SQLite recover table.
SQLite databases use a consistent string encoding for the entire
database. Detect the database's encoding and use it when setting text
results.
BUG=none
Review URL: https://chromiumcodereview.appspot.com/13940011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195999 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/sqlite')
-rw-r--r-- | third_party/sqlite/src/src/recover-alt.c | 66 | ||||
-rw-r--r-- | third_party/sqlite/src/test/recover1.test | 91 |
2 files changed, 156 insertions, 1 deletions
diff --git a/third_party/sqlite/src/src/recover-alt.c b/third_party/sqlite/src/src/recover-alt.c index 1a4ffe5..cc7a423 100644 --- a/third_party/sqlite/src/src/recover-alt.c +++ b/third_party/sqlite/src/src/recover-alt.c @@ -491,6 +491,56 @@ static int getRootPage(sqlite3 *db, const char *zDb, const char *zTable, return rc; } +static int getEncoding(sqlite3 *db, const char *zDb, int* piEncoding){ + char *zSql = sqlite3_mprintf("PRAGMA %s.encoding", zDb); + if( !zSql ){ + return SQLITE_NOMEM; + } + + sqlite3_stmt *pStmt = 0; + int rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Require a result. */ + rc = sqlite3_step(pStmt); + if( rc==SQLITE_DONE ){ + /* This case should not be possible. */ + rc = SQLITE_CORRUPT; + }else if( rc==SQLITE_ROW ){ + if( sqlite3_column_type(pStmt, 0)==SQLITE_TEXT ){ + const char* z = sqlite3_column_text(pStmt, 0); + /* These strings match the literals in pragma.c. */ + if( !strcmp(z, "UTF-16le") ){ + *piEncoding = SQLITE_UTF16LE; + }else if( !strcmp(z, "UTF-16be") ){ + *piEncoding = SQLITE_UTF16BE; + }else if( !strcmp(z, "UTF-8") ){ + *piEncoding = SQLITE_UTF8; + }else{ + /* This case should not be possible. */ + *piEncoding = SQLITE_UTF8; + } + }else{ + /* This case should not be possible. */ + *piEncoding = SQLITE_UTF8; + } + + /* Require only one result. */ + rc = sqlite3_step(pStmt); + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + }else if( rc==SQLITE_ROW ){ + /* This case should not be possible. */ + rc = SQLITE_CORRUPT; + } + } + sqlite3_finalize(pStmt); + return rc; +} + /* Cursor for iterating interior nodes. Interior page cells contain a * child page number and a rowid. The child page contains items left * of the rowid (less than). The rightmost page of the subtree is @@ -1451,6 +1501,7 @@ typedef struct RecoverCursor RecoverCursor; struct RecoverCursor { sqlite3_vtab_cursor base; RecoverLeafCursor *pLeafCursor; + int iEncoding; int bEOF; }; @@ -1466,6 +1517,12 @@ static int recoverOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ return rc; } + int iEncoding = 0; + rc = getEncoding(pRecover->db, pRecover->zDb, &iEncoding); + if( rc!=SQLITE_OK ){ + return rc; + } + unsigned nPageSize; Pager *pPager; rc = GetPager(pRecover->db, pRecover->zDb, &pPager, &nPageSize); @@ -1487,6 +1544,7 @@ static int recoverOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ memset(pCursor, 0, sizeof(*pCursor)); pCursor->base.pVtab = pVTab; pCursor->pLeafCursor = pLeafCursor; + pCursor->iEncoding = iEncoding; *ppCursor = (sqlite3_vtab_cursor*)pCursor; return SQLITE_OK; @@ -1645,7 +1703,13 @@ static int recoverColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ if( SerialTypeIsBlob(iColType) ){ sqlite3_result_blob(ctx, pColData, l, pFn); }else{ - sqlite3_result_text(ctx, (const char*)pColData, l, pFn); + if( pCursor->iEncoding==SQLITE_UTF16LE ){ + sqlite3_result_text16le(ctx, (const void*)pColData, l, pFn); + }else if( pCursor->iEncoding==SQLITE_UTF16BE ){ + sqlite3_result_text16be(ctx, (const void*)pColData, l, pFn); + }else{ + sqlite3_result_text(ctx, (const char*)pColData, l, pFn); + } } } break; } diff --git a/third_party/sqlite/src/test/recover1.test b/third_party/sqlite/src/test/recover1.test index c3541b7..1d90f09 100644 --- a/third_party/sqlite/src/test/recover1.test +++ b/third_party/sqlite/src/test/recover1.test @@ -335,4 +335,95 @@ do_test recover-types-7.0 { execsql {SELECT rowid, value FROM integers_recover} } {1 0 2 1 3 2 4 -2 5 127 6 -128 7 12345 8 -12345 9 32767 10 -32768 11 1234567 12 -1234567 13 8388607 14 -8388608 15 1234567890 16 -1234567890 17 2147483647 18 -2147483648 19 123456789012345 20 -123456789012345 21 140737488355327 22 -140737488355328 23 9223372036854775807 24 -9223372036854775808} +# If UTF16 support is disabled, ignore the rest of the tests. +# +ifcapable {!utf16} { + finish_test + return +} + +# Baseline UTF-8. +file delete -force test.db +sqlite3 db test.db; +db eval { + PRAGMA encoding = 'UTF-8'; +} + +do_test recover-encoding-1.0 { + execsql { + DROP TABLE IF EXISTS e; + CREATE TABLE e (v TEXT); + INSERT INTO e VALUES('Mjollnir'); + INSERT INTO e VALUES('Mjölnir'); + INSERT INTO e VALUES('Mjǫlnir'); + INSERT INTO e VALUES('Mjölner'); + INSERT INTO e VALUES('Mjølner'); + INSERT INTO e VALUES('ハンマー'); + PRAGMA encoding; + + DROP TABLE IF EXISTS e_recover; + CREATE VIRTUAL TABLE temp.e_recover USING recover( + e, + v TEXT + ); + SELECT rowid, v FROM e_recover ORDER BY rowid; + } +} {UTF-8 1 Mjollnir 2 Mjölnir 3 Mjǫlnir 4 Mjölner 5 Mjølner 6 ハンマー} + +# Reset the database to UTF-16LE. +file delete -force test.db +sqlite3 db test.db; +db eval { + PRAGMA encoding = 'UTF-16LE'; +} + +do_test recover-encoding-2.0 { + execsql { + DROP TABLE IF EXISTS e; + CREATE TABLE e (v TEXT); + INSERT INTO e VALUES('Mjollnir'); + INSERT INTO e VALUES('Mjölnir'); + INSERT INTO e VALUES('Mjǫlnir'); + INSERT INTO e VALUES('Mjölner'); + INSERT INTO e VALUES('Mjølner'); + INSERT INTO e VALUES('ハンマー'); + PRAGMA encoding; + + DROP TABLE IF EXISTS e_recover; + CREATE VIRTUAL TABLE temp.e_recover USING recover( + e, + v TEXT + ); + SELECT rowid, v FROM e_recover ORDER BY rowid; + } +} {UTF-16le 1 Mjollnir 2 Mjölnir 3 Mjǫlnir 4 Mjölner 5 Mjølner 6 ハンマー} + +# Reset the database to UTF-16BE. +file delete -force test.db +sqlite3 db test.db; +db eval { + PRAGMA encoding = 'UTF-16BE'; +} + +do_test recover-encoding-3.0 { + execsql { + DROP TABLE IF EXISTS e; + CREATE TABLE e (v TEXT); + INSERT INTO e VALUES('Mjollnir'); + INSERT INTO e VALUES('Mjölnir'); + INSERT INTO e VALUES('Mjǫlnir'); + INSERT INTO e VALUES('Mjölner'); + INSERT INTO e VALUES('Mjølner'); + INSERT INTO e VALUES('ハンマー'); + PRAGMA encoding; + + DROP TABLE IF EXISTS e_recover; + CREATE VIRTUAL TABLE temp.e_recover USING recover( + e, + v TEXT + ); + SELECT rowid, v FROM e_recover ORDER BY rowid; + } +} {UTF-16be 1 Mjollnir 2 Mjölnir 3 Mjǫlnir 4 Mjölner 5 Mjølner 6 ハンマー} + finish_test |