/ Check-in [e336cf00]
Login

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

Overview
Comment:Fix the CSV extension so that it works with single-column CSV files.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e336cf00486bdc0ec04ecded2b7c874d73a87e6aba3544e3678bedfb9a4af3b6
User & Date: drh 2018-06-02 12:05:18
Context
2018-06-02
17:00
Update a test case in malloc5.test to take into account that malloc() sometimes returns slightly more space than requested. check-in: 3d5eae1c user: dan tags: trunk
16:32
Work around a sanitizer warning about a pointer being only 4-byte aligned instead of 8-byte aligned. Closed-Leaf check-in: 1b807b51 user: drh tags: align8-fix
14:37
Proposed fix for the use of posix_fallocate() so that it handles EINVAL returns correctly. Closed-Leaf check-in: ab3a5539 user: drh tags: einval-from-fallocate
12:05
Fix the CSV extension so that it works with single-column CSV files. check-in: e336cf00 user: drh tags: trunk
11:31
Ensure that sqlite3AuthRead() is only call for TK_COLUMN and TK_TRIGGER expression nodes. This fixes a harmless assert() identified by OSSFuzz. Move the assert() into a position where it is tested even if the authorizer is disabled. check-in: d0c3beef user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/misc/csv.c.

201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
...
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
...
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
**   +  Input comes from p->in.
**   +  Store results in p->z of length p->n.  Space to hold p->z comes
**      from sqlite3_malloc64().
**   +  Keep track of the line number in p->nLine.
**   +  Store the character that terminates the field in p->cTerm.  Store
**      EOF on end-of-file.
**
** Return "" at EOF.  Return 0 on an OOM error.

*/
static char *csv_read_one_field(CsvReader *p){
  int c;
  p->n = 0;
  c = csv_getc(p);
  if( c==EOF ){
    p->cTerm = EOF;
    return "";
  }
  if( c=='"' ){
    int pc, ppc;
    int startLine = p->nLine;
    pc = ppc = 0;
    while( 1 ){
      c = csv_getc(p);
................................................................................
  *ppVtab = (sqlite3_vtab*)pNew;
  if( pNew==0 ) goto csvtab_connect_oom;
  memset(pNew, 0, sizeof(*pNew));
  if( nCol>0 ){
    pNew->nCol = nCol;
  }else{
    do{
      const char *z = csv_read_one_field(&sRdr);
      if( z==0 ) goto csvtab_connect_oom;
      pNew->nCol++;
    }while( sRdr.cTerm==',' );
  }
  pNew->zFilename = CSV_FILENAME;  CSV_FILENAME = 0;
  pNew->zData = CSV_DATA;          CSV_DATA = 0;
#ifdef SQLITE_TEST
  pNew->tstFlags = tstFlags;
................................................................................
  CsvCursor *pCur = (CsvCursor*)cur;
  CsvTable *pTab = (CsvTable*)cur->pVtab;
  int i = 0;
  char *z;
  do{
    z = csv_read_one_field(&pCur->rdr);
    if( z==0 ){
      csv_xfer_error(pTab, &pCur->rdr);
      break;
    }
    if( i<pTab->nCol ){
      if( pCur->aLen[i] < pCur->rdr.n+1 ){
        char *zNew = sqlite3_realloc64(pCur->azVal[i], pCur->rdr.n+1);
        if( zNew==0 ){
          csv_errmsg(&pCur->rdr, "out of memory");







|
>







|







 







|
<







 







<







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
...
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
...
659
660
661
662
663
664
665

666
667
668
669
670
671
672
**   +  Input comes from p->in.
**   +  Store results in p->z of length p->n.  Space to hold p->z comes
**      from sqlite3_malloc64().
**   +  Keep track of the line number in p->nLine.
**   +  Store the character that terminates the field in p->cTerm.  Store
**      EOF on end-of-file.
**
** Return 0 at EOF or on OOM.  On EOF, the p->cTerm character will have
** been set to EOF.
*/
static char *csv_read_one_field(CsvReader *p){
  int c;
  p->n = 0;
  c = csv_getc(p);
  if( c==EOF ){
    p->cTerm = EOF;
    return 0;
  }
  if( c=='"' ){
    int pc, ppc;
    int startLine = p->nLine;
    pc = ppc = 0;
    while( 1 ){
      c = csv_getc(p);
................................................................................
  *ppVtab = (sqlite3_vtab*)pNew;
  if( pNew==0 ) goto csvtab_connect_oom;
  memset(pNew, 0, sizeof(*pNew));
  if( nCol>0 ){
    pNew->nCol = nCol;
  }else{
    do{
      csv_read_one_field(&sRdr);

      pNew->nCol++;
    }while( sRdr.cTerm==',' );
  }
  pNew->zFilename = CSV_FILENAME;  CSV_FILENAME = 0;
  pNew->zData = CSV_DATA;          CSV_DATA = 0;
#ifdef SQLITE_TEST
  pNew->tstFlags = tstFlags;
................................................................................
  CsvCursor *pCur = (CsvCursor*)cur;
  CsvTable *pTab = (CsvTable*)cur->pVtab;
  int i = 0;
  char *z;
  do{
    z = csv_read_one_field(&pCur->rdr);
    if( z==0 ){

      break;
    }
    if( i<pTab->nCol ){
      if( pCur->aLen[i] < pCur->rdr.n+1 ){
        char *zNew = sqlite3_realloc64(pCur->azVal[i], pCur->rdr.n+1);
        if( zNew==0 ){
          csv_errmsg(&pCur->rdr, "out of memory");

Changes to test/csv01.test.

143
144
145
146
147
148
149
150









151
# 2018-04-24
# Memory leak reported on the sqlite-users mailing list by Ralf Junker.
#
do_catchsql_test 4.3 {
  CREATE VIRTUAL TABLE IF NOT EXISTS temp.t1
  USING csv(filename='FileDoesNotExist.csv');
} {1 {cannot open 'FileDoesNotExist.csv' for reading}}










finish_test








>
>
>
>
>
>
>
>
>

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# 2018-04-24
# Memory leak reported on the sqlite-users mailing list by Ralf Junker.
#
do_catchsql_test 4.3 {
  CREATE VIRTUAL TABLE IF NOT EXISTS temp.t1
  USING csv(filename='FileDoesNotExist.csv');
} {1 {cannot open 'FileDoesNotExist.csv' for reading}}

# 2018-06-02
# Problem with single-column CSV support reported on the mailing list
# by Trent W. Buck.
#
do_execsql_test 4.4 {
  CREATE VIRTUAL TABLE temp.trent USING csv(data='1');
  SELECT * FROM trent;
} {1}

finish_test