From 25bac8dbf63b85ef130e38e64f7fc4bfed71ece0 Mon Sep 17 00:00:00 2001 From: SeongTae Jeong Date: Sat, 2 Nov 2024 23:19:05 +0900 Subject: [PATCH 1/2] Check database file encoding to set appropriate opening mode Fix: #3714 --- src/sqlitedb.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/sqlitedb.cpp b/src/sqlitedb.cpp index 8f2cecb41..fa0eb0966 100644 --- a/src/sqlitedb.cpp +++ b/src/sqlitedb.cpp @@ -196,8 +196,43 @@ bool DBBrowserDB::open(const QString& db, bool readOnly) if(tryEncryptionSettings(db, &isEncrypted, &cipherSettings) == false) return false; + // Open database file header to determine encoding + QFile file(db); + if(!file.open(QIODevice::ReadOnly)) + { + lastErrorMessage = tr("Cannot open database file: %1").arg(file.errorString()); + return false; + } + + QByteArray header = file.read(100); + file.close(); + + const char* encodingBytes = header.constData() + 56; + // The variable 'encoding' will have one of the following values: + // 1: UTF-8, 2: UTF-16LE, 3: UTF-16BE + quint32 encoding = ((quint8)encodingBytes[0] << 24) | + ((quint8)encodingBytes[1] << 16) | + ((quint8)encodingBytes[2] << 8) | + ((quint8)encodingBytes[3]); + // Open database file - if(sqlite3_open_v2(db.toUtf8(), &_db, readOnly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE, nullptr) != SQLITE_OK) + int status=0; + if(encoding == 1) + { + status = sqlite3_open_v2( + db.toUtf8(), + &_db, + readOnly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE, + nullptr); + } + else + { + status = sqlite3_open16(db.constData(), &_db); + if (status == SQLITE_OK && readOnly) + sqlite3_exec(_db, "PRAGMA query_only = TRUE;", nullptr, nullptr, nullptr); + } + + if (status != SQLITE_OK) { lastErrorMessage = QString::fromUtf8(sqlite3_errmsg(_db)); return false; From afb2c431945968e893da287f51eaacacb0c21348 Mon Sep 17 00:00:00 2001 From: SeongTae Jeong Date: Sun, 3 Nov 2024 03:27:10 +0900 Subject: [PATCH 2/2] Use the preprocessor macro instead of the magic number for the encoding value --- src/sqlitedb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sqlitedb.cpp b/src/sqlitedb.cpp index fa0eb0966..068750a2a 100644 --- a/src/sqlitedb.cpp +++ b/src/sqlitedb.cpp @@ -209,7 +209,7 @@ bool DBBrowserDB::open(const QString& db, bool readOnly) const char* encodingBytes = header.constData() + 56; // The variable 'encoding' will have one of the following values: - // 1: UTF-8, 2: UTF-16LE, 3: UTF-16BE + // SQLITE_UTF8, SQLITE_UTF16LE, SQLITE_UTF16BE (https://www.sqlite.org/fileformat.html#text_encoding) quint32 encoding = ((quint8)encodingBytes[0] << 24) | ((quint8)encodingBytes[1] << 16) | ((quint8)encodingBytes[2] << 8) | @@ -217,7 +217,7 @@ bool DBBrowserDB::open(const QString& db, bool readOnly) // Open database file int status=0; - if(encoding == 1) + if(encoding == SQLITE_UTF8) { status = sqlite3_open_v2( db.toUtf8(),