aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2019-05-03 19:34:41 +0000
committerdrh <drh@noemail.net>2019-05-03 19:34:41 +0000
commit30d3b0ceb55f4a1fcf661236dee0cd0437f35fcb (patch)
tree0297d9681e5307b0a5ab8e2a5aa0f227d87407b4 /src
parenta51297200ff4c6825e299fab8f9debf25c3e6207 (diff)
downloadsqlite-30d3b0ceb55f4a1fcf661236dee0cd0437f35fcb.tar.gz
sqlite-30d3b0ceb55f4a1fcf661236dee0cd0437f35fcb.zip
Ensure that UTF16 strings are properly zero-terminated before returning them
in an sqlite3_value_text16() request, even if the string is invalid UTF16 because it was formed from an arbitrary and/or odd-length BLOB. FossilOrigin-Name: 3a16ddf91f0c9c516a7fc2a9d4a4f69a8326f9b8ea66421e9ef1a2d663687b70
Diffstat (limited to 'src')
-rw-r--r--src/vdbemem.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 82f7f3e10..96edebcde 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -270,13 +270,19 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
/*
** It is already known that pMem contains an unterminated string.
** Add the zero terminator.
+**
+** Three bytes of zero are added. In this way, there is guaranteed
+** to be a double-zero byte at an even byte boundary in order to
+** terminate a UTF16 string, even if the initial size of the buffer
+** is an odd number of bytes.
*/
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
- if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
+ if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){
return SQLITE_NOMEM_BKPT;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
+ pMem->z[pMem->n+2] = 0;
pMem->flags |= MEM_Term;
return SQLITE_OK;
}
@@ -350,9 +356,9 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
}
/*
-** Add MEM_Str to the set of representations for the given Mem. Numbers
-** are converted using sqlite3_snprintf(). Converting a BLOB to a string
-** is a no-op.
+** Add MEM_Str to the set of representations for the given Mem. This
+** routine is only called if pMem is a number of some kind, not a NULL
+** or a BLOB.
**
** Existing representations MEM_Int and MEM_Real are invalidated if
** bForce is true but are retained if bForce is false.