Fossil

Check-in [60acb3183d]
Login

Check-in [60acb3183d]

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

Overview
Comment:Fix memory leaks in the TH1 divide-by-zero handling. Add more tests.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 60acb3183d3c1306afcc7b2fff60060bb3e204aa
User & Date: mistachkin 2014-01-03 23:18:33.197
Context
2014-01-04
16:17
Use the latest SQLite 3.8.3 alpha from upstream. ... (check-in: da90bbe591 user: drh tags: trunk)
2014-01-03
23:18
Fix memory leaks in the TH1 divide-by-zero handling. Add more tests. ... (check-in: 60acb3183d user: mistachkin tags: trunk)
2014-01-02
23:08
Never define USE_SYSTEM_SQLITE as empty string: C preprocessor cannot handle that. ... (check-in: a13c37313d user: jan.nijtmans tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
374
375
376
377
378
379
380









381
382
383
384
385
386
387
  cson_value_free(g.json.gc.v);
  memset(&g.json, 0, sizeof(g.json));
#endif
  free(g.zErrMsg);
  if(g.db){
    db_close(0);
  }









}

/*
** Convert all arguments from mbcs (or unicode) to UTF-8. Then
** search g.argv for arguments "--args FILENAME". If found, then
** (1) remove the two arguments from g.argv
** (2) Read the file FILENAME







>
>
>
>
>
>
>
>
>







374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
  cson_value_free(g.json.gc.v);
  memset(&g.json, 0, sizeof(g.json));
#endif
  free(g.zErrMsg);
  if(g.db){
    db_close(0);
  }
  /*
  ** FIXME: The next two lines cannot always be enabled; however, they
  **        are useful for tracking down TH1 memory leaks.
  */
  /*
  if( g.interp ){
    Th_DeleteInterp(g.interp); g.interp = 0;
  }
  assert( Th_GetOutstandingMalloc()==0 ); */
}

/*
** Convert all arguments from mbcs (or unicode) to UTF-8. Then
** search g.argv for arguments "--args FILENAME". If found, then
** (1) remove the two arguments from g.argv
** (2) Read the file FILENAME
Changes to src/th.c.
1876
1877
1878
1879
1880
1881
1882
1883

1884
1885
1886
1887
1888
1889
1890

1891
1892
1893
1894
1895
1896
1897
    if( rc==TH_OK && eArgType==ARG_INTEGER ){
      int iRes = 0;
      switch( pExpr->pOp->eOp ) {
        case OP_MULTIPLY:     iRes = iLeft*iRight;  break;
        case OP_DIVIDE:
          if( !iRight ){
            Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
            return TH_ERROR;

          }
          iRes = iLeft/iRight;
          break;
        case OP_MODULUS:
          if( !iRight ){
            Th_ErrorMessage(interp, "Modulo by 0:", zLeft, nLeft);
            return TH_ERROR;

          }
          iRes = iLeft%iRight;
          break;
        case OP_ADD:          iRes = iLeft+iRight;  break;
        case OP_SUBTRACT:     iRes = iLeft-iRight;  break;
        case OP_LEFTSHIFT:    iRes = iLeft<<iRight; break;
        case OP_RIGHTSHIFT:   iRes = iLeft>>iRight; break;







|
>






|
>







1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
    if( rc==TH_OK && eArgType==ARG_INTEGER ){
      int iRes = 0;
      switch( pExpr->pOp->eOp ) {
        case OP_MULTIPLY:     iRes = iLeft*iRight;  break;
        case OP_DIVIDE:
          if( !iRight ){
            Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
            rc = TH_ERROR;
            goto finish;
          }
          iRes = iLeft/iRight;
          break;
        case OP_MODULUS:
          if( !iRight ){
            Th_ErrorMessage(interp, "Modulo by 0:", zLeft, nLeft);
            rc = TH_ERROR;
            goto finish;
          }
          iRes = iLeft%iRight;
          break;
        case OP_ADD:          iRes = iLeft+iRight;  break;
        case OP_SUBTRACT:     iRes = iLeft-iRight;  break;
        case OP_LEFTSHIFT:    iRes = iLeft<<iRight; break;
        case OP_RIGHTSHIFT:   iRes = iLeft>>iRight; break;
1914
1915
1916
1917
1918
1919
1920
1921

1922
1923
1924
1925
1926
1927
1928
      Th_SetResultInt(interp, iRes);
    }else if( rc==TH_OK && eArgType==ARG_NUMBER ){
      switch( pExpr->pOp->eOp ) {
        case OP_MULTIPLY: Th_SetResultDouble(interp, fLeft*fRight);  break;
        case OP_DIVIDE:
          if( fRight==0.0 ){
            Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
            return TH_ERROR;

          }
          Th_SetResultDouble(interp, fLeft/fRight);
          break;
        case OP_ADD:      Th_SetResultDouble(interp, fLeft+fRight);  break;
        case OP_SUBTRACT: Th_SetResultDouble(interp, fLeft-fRight);  break;
        case OP_LT:       Th_SetResultInt(interp, fLeft<fRight);  break;
        case OP_GT:       Th_SetResultInt(interp, fLeft>fRight);  break;







|
>







1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
      Th_SetResultInt(interp, iRes);
    }else if( rc==TH_OK && eArgType==ARG_NUMBER ){
      switch( pExpr->pOp->eOp ) {
        case OP_MULTIPLY: Th_SetResultDouble(interp, fLeft*fRight);  break;
        case OP_DIVIDE:
          if( fRight==0.0 ){
            Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
            rc = TH_ERROR;
            goto finish;
          }
          Th_SetResultDouble(interp, fLeft/fRight);
          break;
        case OP_ADD:      Th_SetResultDouble(interp, fLeft+fRight);  break;
        case OP_SUBTRACT: Th_SetResultDouble(interp, fLeft-fRight);  break;
        case OP_LT:       Th_SetResultInt(interp, fLeft<fRight);  break;
        case OP_GT:       Th_SetResultInt(interp, fLeft>fRight);  break;
1940
1941
1942
1943
1944
1945
1946


1947
1948
1949
1950
1951
1952
1953
      }
      switch( pExpr->pOp->eOp ) {
        case OP_SEQ:       Th_SetResultInt(interp, iEqual); break;
        case OP_SNE:       Th_SetResultInt(interp, !iEqual); break;
        default: assert(!"Internal error");
      }
    }



    Th_Free(interp, zLeft);
    Th_Free(interp, zRight);
  }

  return rc;
}







>
>







1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
      }
      switch( pExpr->pOp->eOp ) {
        case OP_SEQ:       Th_SetResultInt(interp, iEqual); break;
        case OP_SNE:       Th_SetResultInt(interp, !iEqual); break;
        default: assert(!"Internal error");
      }
    }

   finish:

    Th_Free(interp, zLeft);
    Th_Free(interp, zRight);
  }

  return rc;
}
Changes to src/th_main.c.
55
56
57
58
59
60
61







62
63
64
65
66
67
68
static void xFree(void *p){
  if( p ){
    nOutstandingMalloc--;
  }
  free(p);
}
static Th_Vtab vtab = { xMalloc, xFree };








/*
** Generate a TH1 trace message if debugging is enabled.
*/
void Th_Trace(const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);







>
>
>
>
>
>
>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
static void xFree(void *p){
  if( p ){
    nOutstandingMalloc--;
  }
  free(p);
}
static Th_Vtab vtab = { xMalloc, xFree };

/*
** Returns the number of outstanding TH1 memory allocations.
*/
int Th_GetOutstandingMalloc(){
  return nOutstandingMalloc;
}

/*
** Generate a TH1 trace message if debugging is enabled.
*/
void Th_Trace(const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);
Changes to test/th1.test.
83
84
85
86
87
88
89






















fossil test-th-eval "expr 42.0/0"
test th1-divide-by-zero-3 {$RESULT eq {TH_ERROR: Divide by 0: 42.0}}

###############################################################################

fossil test-th-eval "expr 42.0/0.0"
test th1-divide-by-zero-4 {$RESULT eq {TH_ERROR: Divide by 0: 42.0}}





























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
fossil test-th-eval "expr 42.0/0"
test th1-divide-by-zero-3 {$RESULT eq {TH_ERROR: Divide by 0: 42.0}}

###############################################################################

fossil test-th-eval "expr 42.0/0.0"
test th1-divide-by-zero-4 {$RESULT eq {TH_ERROR: Divide by 0: 42.0}}

###############################################################################

fossil test-th-eval "expr 42%0"
test th1-modulus-by-zero-1 {$RESULT eq {TH_ERROR: Modulo by 0: 42}}

###############################################################################

fossil test-th-eval "expr 42%0.0"
test th1-modulus-by-zero-2 {$RESULT eq {TH_ERROR: expected integer, got: "0.0"}}

###############################################################################

fossil test-th-eval "expr 42.0%0"
test th1-modulus-by-zero-3 {$RESULT eq \
{TH_ERROR: expected integer, got: "42.0"}}

###############################################################################

fossil test-th-eval "expr 42.0%0.0"
test th1-modulus-by-zero-4 {$RESULT eq \
{TH_ERROR: expected integer, got: "42.0"}}