/ Check-in [3f657e88]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Prevent buffer overruns when converting malformed UTF16 to UTF8. Ticket #3482. (CVS 5869)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:3f657e88767f60d305dd6151e7aa54363341d052
User & Date: drh 2008-11-07 03:29:34
Context
2008-11-10
17:08
Fixed typos; Consistent use of Mac OS X name; (CVS 5870) check-in: dfc94743 user: shane tags: trunk
2008-11-07
03:29
Prevent buffer overruns when converting malformed UTF16 to UTF8. Ticket #3482. (CVS 5869) check-in: 3f657e88 user: drh tags: trunk
00:24
Prevent a rollback from crashing if the sector-size field of the rollback journal is corrupted. (CVS 5868) check-in: cf9d1d93 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/utf.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
...
240
241
242
243
244
245
246

247
248
249
250
251
252
253
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.65 2008/08/12 15:04:59 danielk1977 Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
................................................................................
    int rc;
    rc = sqlite3VdbeMemMakeWriteable(pMem);
    if( rc!=SQLITE_OK ){
      assert( rc==SQLITE_NOMEM );
      return SQLITE_NOMEM;
    }
    zIn = (u8*)pMem->z;
    zTerm = &zIn[pMem->n];
    while( zIn<zTerm ){
      temp = *zIn;
      *zIn = *(zIn+1);
      zIn++;
      *zIn++ = temp;
    }
    pMem->enc = desiredEnc;
................................................................................
  /* Set len to the maximum number of bytes required in the output buffer. */
  if( desiredEnc==SQLITE_UTF8 ){
    /* When converting from UTF-16, the maximum growth results from
    ** translating a 2-byte character to a 4-byte UTF-8 character.
    ** A single byte is required for the output string
    ** nul-terminator.
    */

    len = pMem->n * 2 + 1;
  }else{
    /* When converting from UTF-8 to UTF-16 the maximum growth is caused
    ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
    ** character. Two bytes are required in the output buffer for the
    ** nul-terminator.
    */







|







 







|







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.66 2008/11/07 03:29:34 drh Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
................................................................................
    int rc;
    rc = sqlite3VdbeMemMakeWriteable(pMem);
    if( rc!=SQLITE_OK ){
      assert( rc==SQLITE_NOMEM );
      return SQLITE_NOMEM;
    }
    zIn = (u8*)pMem->z;
    zTerm = &zIn[pMem->n&~1];
    while( zIn<zTerm ){
      temp = *zIn;
      *zIn = *(zIn+1);
      zIn++;
      *zIn++ = temp;
    }
    pMem->enc = desiredEnc;
................................................................................
  /* Set len to the maximum number of bytes required in the output buffer. */
  if( desiredEnc==SQLITE_UTF8 ){
    /* When converting from UTF-16, the maximum growth results from
    ** translating a 2-byte character to a 4-byte UTF-8 character.
    ** A single byte is required for the output string
    ** nul-terminator.
    */
    pMem->n &= ~1;
    len = pMem->n * 2 + 1;
  }else{
    /* When converting from UTF-8 to UTF-16 the maximum growth is caused
    ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
    ** character. Two bytes are required in the output buffer for the
    ** nul-terminator.
    */

Changes to test/utf16align.test.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
76
77
78
79
80
81
82
83











84
#***********************************************************************
# 
# This file contains code to verify that the SQLITE_UTF16_ALIGNED
# flag passed into the sqlite3_create_collation() function insures
# that all strings passed to that function are aligned on an even
# byte boundary.
#
# $Id: utf16align.test,v 1.1 2006/02/16 18:16:38 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Skip this entire test if we do not support UTF16
#
ifcapable !utf16 {
................................................................................
  set unaligned_string_counter 0
  execsql {
    CREATE INDEX t1i2 ON t1(spacer, a);
  }
  expr {$unaligned_string_counter>0}
} 0
integrity_check utf16align-1.4












finish_test







|







 








>
>
>
>
>
>
>
>
>
>
>

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#***********************************************************************
# 
# This file contains code to verify that the SQLITE_UTF16_ALIGNED
# flag passed into the sqlite3_create_collation() function insures
# that all strings passed to that function are aligned on an even
# byte boundary.
#
# $Id: utf16align.test,v 1.2 2008/11/07 03:29:34 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Skip this entire test if we do not support UTF16
#
ifcapable !utf16 {
................................................................................
  set unaligned_string_counter 0
  execsql {
    CREATE INDEX t1i2 ON t1(spacer, a);
  }
  expr {$unaligned_string_counter>0}
} 0
integrity_check utf16align-1.4

# ticket #3482
#
db close
sqlite3 db :memory:
do_test utf16align-2.1 {
  db eval {
    PRAGMA encoding=UTF16be;
    SELECT hex(ltrim(x'6efcda'));
  }
} {6EFC}

finish_test