SQLite

Check-in [465a15c5]
Login

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

Overview
Comment:Fix buffer underflows in the zipfile extension associated with zero-length or NULL filename in the ZIP archive. But report on the mailing list by Yongheng and Rui.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 465a15c5c2077011befa854a77f9d295bb751ef20b7d2937ac0ba47cc84587c9
User & Date: drh 2019-12-27 00:19:53
Context
2019-12-27
01:50
Ensure that the Pager.changeCountDone flag is cleared whenever dropping the write lock, even when transitioning from EXCLUSIVE locking mode into NORMAL locking mode while in WAL mode. Ticket [fb3b3024ea238d5c]. (check-in: 846b1de6 user: drh tags: trunk)
00:19
Fix buffer underflows in the zipfile extension associated with zero-length or NULL filename in the ZIP archive. But report on the mailing list by Yongheng and Rui. (check-in: 465a15c5 user: drh tags: trunk)
2019-12-26
23:40
If an UPSERT can cause an Abort due to a constraint failure, make sure the query planner knows this. Ticket [7c13db5c3bf74001]. (check-in: f14ce948 user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/misc/zipfile.c.

1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444

/*
** Both (const char*) arguments point to nul-terminated strings. Argument
** nB is the value of strlen(zB). This function returns 0 if the strings are
** identical, ignoring any trailing '/' character in either path.  */
static int zipfileComparePath(const char *zA, const char *zB, int nB){
  int nA = (int)strlen(zA);
  if( zA[nA-1]=='/' ) nA--;
  if( zB[nB-1]=='/' ) nB--;
  if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
  return 1;
}

static int zipfileBegin(sqlite3_vtab *pVtab){
  ZipfileTab *pTab = (ZipfileTab*)pVtab;
  int rc = SQLITE_OK;







|
|







1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444

/*
** Both (const char*) arguments point to nul-terminated strings. Argument
** nB is the value of strlen(zB). This function returns 0 if the strings are
** identical, ignoring any trailing '/' character in either path.  */
static int zipfileComparePath(const char *zA, const char *zB, int nB){
  int nA = (int)strlen(zA);
  if( nA>0 && zA[nA-1]=='/' ) nA--;
  if( nB>0 && zB[nB-1]=='/' ) nB--;
  if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
  return 1;
}

static int zipfileBegin(sqlite3_vtab *pVtab){
  ZipfileTab *pTab = (ZipfileTab*)pVtab;
  int rc = SQLITE_OK;
1624
1625
1626
1627
1628
1629
1630
1631
1632

1633

1634

1635

1636
1637
1638
1639
1640
1641
1642
    }

    if( rc==SQLITE_OK && bIsDir ){
      /* For a directory, check that the last character in the path is a
      ** '/'. This appears to be required for compatibility with info-zip
      ** (the unzip command on unix). It does not create directories
      ** otherwise.  */
      if( zPath[nPath-1]!='/' ){
        zFree = sqlite3_mprintf("%s/", zPath);

        if( zFree==0 ){ rc = SQLITE_NOMEM; }

        zPath = (const char*)zFree;

        nPath = (int)strlen(zPath);

      }
    }

    /* Check that we're not inserting a duplicate entry -OR- updating an
    ** entry with a path, thereby making it into a duplicate. */
    if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
      ZipfileEntry *p;







|

>
|
>
|
>
|
>







1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
    }

    if( rc==SQLITE_OK && bIsDir ){
      /* For a directory, check that the last character in the path is a
      ** '/'. This appears to be required for compatibility with info-zip
      ** (the unzip command on unix). It does not create directories
      ** otherwise.  */
      if( nPath<=0 || zPath[nPath-1]!='/' ){
        zFree = sqlite3_mprintf("%s/", zPath);
        zPath = (const char*)zFree;
        if( zFree==0 ){
          rc = SQLITE_NOMEM;
          nPath = 0;
        }else{
          nPath = (int)strlen(zPath);
        }
      }
    }

    /* Check that we're not inserting a duplicate entry -OR- updating an
    ** entry with a path, thereby making it into a duplicate. */
    if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
      ZipfileEntry *p;

Changes to test/zipfile.test.

816
817
818
819
820
821
822















823
824
  CREATE TABLE t1(x char);
  INSERT INTO t1(x) VALUES('1');
  INSERT INTO t1(x) SELECT zipfile(x, 'xyz') FROM t1;
  INSERT INTO t1(x) SELECT zipfile(x, 'uvw') FROM t1;
  SELECT count(*) FROM t1;
  PRAGMA integrity_check;
} {3 ok}
















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
  CREATE TABLE t1(x char);
  INSERT INTO t1(x) VALUES('1');
  INSERT INTO t1(x) SELECT zipfile(x, 'xyz') FROM t1;
  INSERT INTO t1(x) SELECT zipfile(x, 'uvw') FROM t1;
  SELECT count(*) FROM t1;
  PRAGMA integrity_check;
} {3 ok}

# 2019-12-26 More problems in zipfile from the Yongheng and Rui fuzzer
#
do_execsql_test 15.10 {
  DROP TABLE IF EXISTS t1;
  CREATE VIRTUAL TABLE t1 USING zipfile(null);
  REPLACE INTO t1 VALUES(null,null,0,null,null,null,null);
} {}
do_execsql_test 15.20 {
  DROP TABLE IF EXISTS t2;
  CREATE VIRTUAL TABLE t2 USING zipfile(null);
  REPLACE INTO t2 values(null,null,null,null,null,10,null);
} {}



finish_test