1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-10-23 21:49:02 +03:00

Follow documented behavior when casting a zeroblob() to text on a UTF-16

database. [bugs:/info/2026-10-23T12:45:59Z|bug 2026-10-23T12:45:59Z]

FossilOrigin-Name: 8a0296aa4db20cdcbbfaa0e4c61b5fe339b0514cf73832253ff0abd1ce59d31c
This commit is contained in:
drh
2026-10-23 13:06:30 +00:00
parent 47f34d87e3
commit 0bb1247fca
4 changed files with 91 additions and 8 deletions

View File

@@ -1,5 +1,5 @@
C Merge\sthe\sFTS5\sfix\sfrom\sbranch-3.54
D 2026-10-23T12:51:22.852
C Follow\sdocumented\sbehavior\swhen\scasting\sa\szeroblob()\sto\stext\son\sa\sUTF-16\ndatabase.\s[bugs:/info/2026-10-23T12:45:59Z|bug\s2026-10-23T12:45:59Z]
D 2026-10-23T13:06:30.822
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -877,7 +877,7 @@ F src/vacuum.c d3d35d8ae893d419ade5fa196d761a83bddcbb62137a1a157ae751ef38b26e82
F src/vdbe.c 7bb9e161f05986446186513a5c9498455930069c2177b12e074a46fa006890c5
F src/vdbe.h b6ffb28da04363fd5d439b8204118fd3f2e751abe4f8e3edb089155fb90d4607
F src/vdbeInt.h 581b112c6a763a5871ae1d2b948c5288e749d03c7e3829ebce2738402fe21074
F src/vdbeapi.c ebaf26be7511d002a573312ddd1976199b5aa24e8be6446aa32438c99f8f17c4
F src/vdbeapi.c 4b38eb061fe6a8e96055e74d9301f0f36e453855e650a3e5fdd25ad45c7d0d7e
F src/vdbeaux.c 7e3975222531284ff14cb1be93b5751f6a3392a56d86d6329fcaa120471f56f3
F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
F src/vdbemem.c cf4000a8b355be2028b290516898ff99d611c0d33397ac6c4f6d77f84dcd39fb
@@ -2196,7 +2196,7 @@ F test/without_rowid6.test efbd7add62c59bf5ca97bf8da674e734e6a70ef979234e8161668
F test/without_rowid7.test 747d3fbef7108d416d6416694b03d8ff046dc9cc82b3d911715feb472444b95a
F test/wordcount.c d721a4b6fae93e6e33449700bce1686bc23257c27425bc3ef1599dc912adec66
F test/writecrash.test 13520af28f376bfc8c0bcd130efc1fff20bb165198e8b94cf153f1f754154bb9
F test/zeroblob.test 7b74cefc7b281dfa2b07cd237987fbe94b4a2037a7771e9e83f2d5f608b1d99e
F test/zeroblob.test ad710990fa13fe969101b5c2a52e95f62f4c16f75ad306eb78a6c05dc9a12e97
F test/zeroblobfault.test 861d8191a0d944dfebb3cb4d2c5b4e46a5a119eaec5a63dd996c2389f8063441
F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc
F test/zipfile.test 88b8b8babbe24dd3c1e58e8f96685429029c283fbf54b6df07b145b66032de9a
@@ -2297,8 +2297,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
P b33ff35e6246a9dc62205db244511eead28fae90cea686e205effae5e6cc5b49 599f3345b99b79e11a71bd0087555d0980f2af5cffb6b78683a5027e78f67831
R dba6315bf647db8443d61e41b60ad9e9
P 320cb1f51382868ed576d8fa52c75672a2c3e4cee99f868385645bd9a370457a
R 0517e9b64f9f1be95cb3761b01d34e64
U drh
Z 6bee0e48227c051076b2df8029557200
Z fe678a626872621c9456ec3e5b057ad7
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
320cb1f51382868ed576d8fa52c75672a2c3e4cee99f868385645bd9a370457a
8a0296aa4db20cdcbbfaa0e4c61b5fe339b0514cf73832253ff0abd1ce59d31c

View File

@@ -691,6 +691,7 @@ int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
}
#ifndef SQLITE_OMIT_INCRBLOB
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
pOut->enc = pCtx->enc;
return SQLITE_OK;
#else
return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
@@ -2017,6 +2018,7 @@ int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
#else
rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
#endif
p->aVar[i-1].enc = ENC(p->db);
sqlite3_mutex_leave(p->db->mutex);
}
return rc;

View File

@@ -339,5 +339,86 @@ do_execsql_test 13.100 {
SELECT a, quote(b), length(b), c FROM t1;
} {1 X'0000000000000000' 8 3}
# 2026-10-23 https://sqlite.org/bugs/info/420911fdac2d68af
#
# In a non-UTF-8 database, a zeroblob() used as text was formerly
# converted from UTF-8, so each zero byte became one character of the
# database encoding. A zeroblob value must read back as text identically
# to the same bytes supplied as a BLOB literal or stored in a table.
#
foreach {tn enc} {14 UTF-16le 15 UTF-16be} {
reset_db
db eval "PRAGMA encoding='$enc'"
do_execsql_test $tn.1 {
CREATE TABLE t1(b);
INSERT INTO t1 VALUES(zeroblob(4));
CREATE TABLE t2(c);
INSERT INTO t2 VALUES('ab'),('abc');
}
# zeroblob(4) cast to text is the same 4 bytes as the literal, the
# stored value, and the value from a materialized CTE.
do_execsql_test $tn.2 {
SELECT hex(CAST(zeroblob(4) AS TEXT));
} {00000000}
do_execsql_test $tn.3 {
SELECT hex(CAST(x'00000000' AS TEXT));
} {00000000}
do_execsql_test $tn.4 {
SELECT hex(CAST(b AS TEXT)) FROM t1;
} {00000000}
do_execsql_test $tn.5 {
WITH x AS MATERIALIZED (SELECT zeroblob(4) AS b FROM t1)
SELECT hex(CAST(b AS TEXT)) FROM x;
} {00000000}
# The value compares equal, and has the same length, either way.
do_execsql_test $tn.6 {
SELECT CAST(zeroblob(4) AS TEXT)=CAST(x'00000000' AS TEXT);
} {1}
do_execsql_test $tn.7 {
SELECT octet_length(CAST(zeroblob(4) AS TEXT)),
octet_length(CAST(x'00000000' AS TEXT));
} {4 4}
# upper()/lower() see the value as the database encoding, not UTF-8.
do_execsql_test $tn.8 {
SELECT hex(upper(zeroblob(4))), hex(upper(x'00000000'));
} {00000000 00000000}
do_execsql_test $tn.9 {
SELECT hex(lower(zeroblob(4))), hex(lower(x'00000000'));
} {00000000 00000000}
# The plan no longer changes the result: inlined and materialized agree.
do_execsql_test $tn.10 {
WITH x AS (SELECT zeroblob(length(c)) AS z FROM t2)
SELECT count(*) FROM (SELECT 1 FROM x GROUP BY upper(z));
} {1}
do_execsql_test $tn.11 {
WITH x AS MATERIALIZED (SELECT zeroblob(length(c)) AS z FROM t2)
SELECT count(*) FROM (SELECT 1 FROM x GROUP BY upper(z));
} {1}
# sqlite3_bind_zeroblob() and sqlite3_bind_zeroblob64() behave like a
# bound BLOB of the same zero bytes.
set stmt [sqlite3_prepare db {SELECT hex(CAST(?1 AS TEXT))} -1 dummy]
do_test $tn.12 {
sqlite3_bind_zeroblob $stmt 1 4
sqlite3_step $stmt
set ret [sqlite3_column_text $stmt 0]
sqlite3_reset $stmt
set ret
} {00000000}
do_test $tn.13 {
sqlite3_bind_zeroblob64 $stmt 1 4
sqlite3_step $stmt
set ret [sqlite3_column_text $stmt 0]
sqlite3_reset $stmt
set ret
} {00000000}
sqlite3_finalize $stmt
}
reset_db
test_restore_config_pagecache
finish_test