SQLite

Check-in [81fdbe0cc5]
Login

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

Overview
Comment:Prevent users from creating zipfile() virtual tables without an argument.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 81fdbe0cc5a360f818078d47a5888d0a29d555927da279a9a0213702d74ef09a
User & Date: dan 2018-01-30 14:07:55.726
Context
2018-01-30
17:43
Add tests cases for the zipfile extension. (check-in: 13b786dafd user: dan tags: trunk)
14:07
Prevent users from creating zipfile() virtual tables without an argument. (check-in: 81fdbe0cc5 user: dan tags: trunk)
2018-01-29
19:47
Add unix-only tests to check that the "unzip" program can unpack archives generated by the zipfile extension. (check-in: 438c5c5237 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/misc/zipfile.c.
313
314
315
316
317
318
319















320
321
322
323
324
325
326
  char **pzErr
){
  int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE;
  int nFile = 0;
  const char *zFile = 0;
  ZipfileTab *pNew = 0;
  int rc;
















  if( argc>3 ){
    zFile = argv[3];
    nFile = (int)strlen(zFile)+1;
  }

  rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);







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







313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  char **pzErr
){
  int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE;
  int nFile = 0;
  const char *zFile = 0;
  ZipfileTab *pNew = 0;
  int rc;

  /* If the table name is not "zipfile", require that the argument be
  ** specified. This stops zipfile tables from being created as:
  **
  **   CREATE VIRTUAL TABLE zzz USING zipfile();
  **
  ** It does not prevent:
  **
  **   CREATE VIRTUAL TABLE zipfile USING zipfile();
  */
  assert( 0==sqlite3_stricmp(argv[0], "zipfile") );
  if( (0!=sqlite3_stricmp(argv[2], "zipfile") && argc<4) || argc>4 ){
    *pzErr = sqlite3_mprintf("zipfile constructor requires one argument");
    return SQLITE_ERROR;
  }

  if( argc>3 ){
    zFile = argv[3];
    nFile = (int)strlen(zFile)+1;
  }

  rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
      sqlite3_result_error_nomem(context);
    }else{
      sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
      sqlite3_free(zRes);
    }
  }
}

static void zipfileFunctionBlob(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  ZipfileCsr *pCsr;
  ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
  ZipfileEntry *p;
  int nBody = 0;
  int nCds = 0;
  int nEocd = ZIPFILE_EOCD_FIXED_SZ;
  ZipfileEOCD eocd;

  u8 *aZip;
  int nZip;

  u8 *aBody;
  u8 *aCds;

  pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
  if( pCsr->pFile || pTab->zFile ){
    sqlite3_result_error(context, "illegal use of zipfile_blob()", -1);
    return;
  }

  /* Figure out how large the final file will be */
  for(p=pTab->pFirstEntry; p; p=p->pNext){
    nBody += ZIPFILE_LFH_FIXED_SZ + p->cds.nFile + 9 + p->cds.szCompressed;
    nCds += ZIPFILE_CDS_FIXED_SZ + p->cds.nFile + 9;
  }

  /* Allocate space to create the serialized file */
  nZip = nBody + nCds + nEocd;
  aZip = (u8*)sqlite3_malloc(nZip);
  if( aZip==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }
  aBody = aZip;
  aCds = &aZip[nBody];

  /* Populate the body and CDS */
  memset(&eocd, 0, sizeof(eocd));
  for(p=pTab->pFirstEntry; p; p=p->pNext){
    p->cds.iOffset = (aBody - aZip);
    aBody += zipfileSerializeLFH(p, aBody);
    if( p->cds.szCompressed ){
      memcpy(aBody, p->aData, p->cds.szCompressed);
      aBody += p->cds.szCompressed;
    }
    aCds += zipfileSerializeCDS(p, aCds);
    eocd.nEntry++;
  }

  /* Append the EOCD record */
  assert( aBody==&aZip[nBody] );
  assert( aCds==&aZip[nBody+nCds] );
  eocd.nEntryTotal = eocd.nEntry;
  eocd.nSize = nCds;
  eocd.iOffset = nBody;
  zipfileSerializeEOCD(&eocd, aCds);

  sqlite3_result_blob(context, aZip, nZip, zipfileFree);
}


/*
** xFindFunction method.
*/
static int zipfileFindFunction(
  sqlite3_vtab *pVtab,            /* Virtual table handle */
  int nArg,                       /* Number of SQL function arguments */
  const char *zName,              /* Name of SQL function */
  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
  void **ppArg                    /* OUT: User data for *pxFunc */
){
  if( nArg>0 ){
    if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
      *pxFunc = zipfileFunctionCds;
      *ppArg = (void*)pVtab;
      return 1;
    }
    if( sqlite3_stricmp("zipfile_blob", zName)==0 ){
      *pxFunc = zipfileFunctionBlob;
      *ppArg = (void*)pVtab;
      return 1;
    }
  }

  return 0;
}

typedef struct ZipfileBuffer ZipfileBuffer;
struct ZipfileBuffer {







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

















<
<
<
<
<







1735
1736
1737
1738
1739
1740
1741


































































1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758





1759
1760
1761
1762
1763
1764
1765
      sqlite3_result_error_nomem(context);
    }else{
      sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
      sqlite3_free(zRes);
    }
  }
}



































































/*
** xFindFunction method.
*/
static int zipfileFindFunction(
  sqlite3_vtab *pVtab,            /* Virtual table handle */
  int nArg,                       /* Number of SQL function arguments */
  const char *zName,              /* Name of SQL function */
  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
  void **ppArg                    /* OUT: User data for *pxFunc */
){
  if( nArg>0 ){
    if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
      *pxFunc = zipfileFunctionCds;
      *ppArg = (void*)pVtab;
      return 1;
    }





  }

  return 0;
}

typedef struct ZipfileBuffer ZipfileBuffer;
struct ZipfileBuffer {
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
    zipfileRollback,           /* xRollback */
    zipfileFindFunction,       /* xFindMethod */
    0,                         /* xRename */
  };

  int rc = sqlite3_create_module(db, "zipfile"  , &zipfileModule, 0);
  if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
  if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_blob", -1);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0, 
        zipfileStep, zipfileFinal
    );
  }
  return rc;
}







<







2031
2032
2033
2034
2035
2036
2037

2038
2039
2040
2041
2042
2043
2044
    zipfileRollback,           /* xRollback */
    zipfileFindFunction,       /* xFindMethod */
    0,                         /* xRename */
  };

  int rc = sqlite3_create_module(db, "zipfile"  , &zipfileModule, 0);
  if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);

  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0, 
        zipfileStep, zipfileFinal
    );
  }
  return rc;
}
Changes to test/zipfile.test.
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
}

do_catchsql_test 3.2 {
  SELECT rowid FROM x1
} {1 {no such column: rowid}}

#-------------------------------------------------------------------------
reset_db
forcedelete test.zip
load_static_extension db zipfile

do_execsql_test 4.0 {
  CREATE VIRTUAL TABLE x2 USING zipfile();
  INSERT INTO x2(name, data) VALUES('dir1/', NULL);
  INSERT INTO x2(name, data) VALUES('file1', '1234');
  INSERT INTO x2(name, data) VALUES('dir1/file2', '5678');
  SELECT name, data FROM x2
} {
  dir1/ {} file1 1234 dir1/file2 5678
}

do_test 4.1 {
  set data [db one {SELECT zipfile_blob(z) FROM x2 LIMIT 1}]
  db eval { SELECT name, data FROM zipfile($data) }
} {dir1/ {} file1 1234 dir1/file2 5678}



finish_test








<
|
<
|
|
|
<
<
<
<
<
<
<
|
|
|
|
<





354
355
356
357
358
359
360

361

362
363
364







365
366
367
368

369
370
371
372
373
}

do_catchsql_test 3.2 {
  SELECT rowid FROM x1
} {1 {no such column: rowid}}

#-------------------------------------------------------------------------

# Test some error conditions.

#
do_catchsql_test 4.1 {
  CREATE VIRTUAL TABLE yyy USING zipfile();







} {1 {zipfile constructor requires one argument}}
do_catchsql_test 4.2 {
  CREATE VIRTUAL TABLE yyy USING zipfile('test.zip', 'test.zip');
} {1 {zipfile constructor requires one argument}}




finish_test