blob: 77e469b1103bf53c4c68714346990b1ddca6730b [file] [log] [blame]
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Darwin Huang <huangdarwin@chromium.org>
Date: Wed, 15 May 2019 18:39:12 -0700
Subject: [PATCH 6/8] Ensure correct zero-termination of UTF16 strings
Backports https://www.sqlite.org/src/info/d612fb7873cf59df
Bug: 959193
---
third_party/sqlite/patched/src/vdbe.c | 3 ++-
third_party/sqlite/patched/src/vdbemem.c | 22 ++++++++++++++++++----
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/third_party/sqlite/patched/src/vdbe.c b/third_party/sqlite/patched/src/vdbe.c
index b563627af83a..a5b0d4b48e28 100644
--- a/third_party/sqlite/patched/src/vdbe.c
+++ b/third_party/sqlite/patched/src/vdbe.c
@@ -1480,7 +1480,7 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){
goto no_mem;
}
MemSetTypeFlag(pOut, MEM_Str);
@@ -1490,6 +1490,7 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
pOut->z[nByte]=0;
pOut->z[nByte+1] = 0;
+ pOut->z[nByte+2] = 0;
pOut->flags |= MEM_Term;
pOut->n = (int)nByte;
pOut->enc = encoding;
diff --git a/third_party/sqlite/patched/src/vdbemem.c b/third_party/sqlite/patched/src/vdbemem.c
index fbcec0f59c18..78a2e3911ba8 100644
--- a/third_party/sqlite/patched/src/vdbemem.c
+++ b/third_party/sqlite/patched/src/vdbemem.c
@@ -94,7 +94,10 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
#ifdef SQLITE_DEBUG
/*
-** Check that string value of pMem agrees with its integer or real value.
+** Validity checks on pMem. pMem holds a string.
+**
+** (1) Check that string value of pMem agrees with its integer or real value.
+** (2) Check that the string is correctly zero terminated**
**
** A single int or real value always converts to the same strings. But
** many different strings can be converted into the same int or real.
@@ -112,11 +115,22 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
**
** This routine is for use inside of assert() statements only.
*/
-int sqlite3VdbeMemConsistentDualRep(Mem *p){
+int sqlite3VdbeMemValidStrRep(Mem *p){
char zBuf[100];
char *z;
int i, j, incr;
if( (p->flags & MEM_Str)==0 ) return 1;
+ if( p->flags & MEM_Term ){
+ /* Insure that the string is properly zero-terminated. Pay particular
+ ** attention to the case where p->n is odd */
+ if( p->z==p->zMalloc && p->szMalloc>0 ){
+ assert( p->enc==SQLITE_UTF8 || p->szMalloc >= ((p->n+1)&~1)+2 );
+ assert( p->enc!=SQLITE_UTF8 || p->szMalloc >= p->n+1 );
+ }
+ assert( p->z[p->n]==0 );
+ assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 );
+ assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 );
+ }
if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1;
if( p->flags & MEM_Int ){
sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i);
@@ -1206,7 +1220,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
|| pVal->db->mallocFailed );
if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
- assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+ assert( sqlite3VdbeMemValidStrRep(pVal) );
return pVal->z;
}else{
return 0;
@@ -1229,7 +1243,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
assert( !sqlite3VdbeMemIsRowSet(pVal) );
if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
- assert( sqlite3VdbeMemConsistentDualRep(pVal) );
+ assert( sqlite3VdbeMemValidStrRep(pVal) );
return pVal->z;
}
if( pVal->flags&MEM_Null ){
--
2.21.0