summaryrefslogtreecommitdiffstats
path: root/third_party/sqlite
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-24 02:13:05 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-24 02:13:05 +0000
commit3f691cf67fee47025e911397e1de3bbed722e4e1 (patch)
treeb7b61f2146273198207545242971bc4fffb7f63b /third_party/sqlite
parent5f5fca52104ad85aeb4e8a3e64e2a2950fb6bae4 (diff)
downloadchromium_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.c66
-rw-r--r--third_party/sqlite/src/test/recover1.test91
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