Fossil SCM

Fix memory leaks in the TH1 divide-by-zero handling. Add more tests.

mistachkin 2014-01-03 23:18 trunk
Commit 60acb3183d3c1306afcc7b2fff60060bb3e204aa
+9
--- src/main.c
+++ src/main.c
@@ -376,10 +376,19 @@
376376
#endif
377377
free(g.zErrMsg);
378378
if(g.db){
379379
db_close(0);
380380
}
381
+ /*
382
+ ** FIXME: The next two lines cannot always be enabled; however, they
383
+ ** are useful for tracking down TH1 memory leaks.
384
+ */
385
+ /*
386
+ if( g.interp ){
387
+ Th_DeleteInterp(g.interp); g.interp = 0;
388
+ }
389
+ assert( Th_GetOutstandingMalloc()==0 ); */
381390
}
382391
383392
/*
384393
** Convert all arguments from mbcs (or unicode) to UTF-8. Then
385394
** search g.argv for arguments "--args FILENAME". If found, then
386395
--- src/main.c
+++ src/main.c
@@ -376,10 +376,19 @@
376 #endif
377 free(g.zErrMsg);
378 if(g.db){
379 db_close(0);
380 }
 
 
 
 
 
 
 
 
 
381 }
382
383 /*
384 ** Convert all arguments from mbcs (or unicode) to UTF-8. Then
385 ** search g.argv for arguments "--args FILENAME". If found, then
386
--- src/main.c
+++ src/main.c
@@ -376,10 +376,19 @@
376 #endif
377 free(g.zErrMsg);
378 if(g.db){
379 db_close(0);
380 }
381 /*
382 ** FIXME: The next two lines cannot always be enabled; however, they
383 ** are useful for tracking down TH1 memory leaks.
384 */
385 /*
386 if( g.interp ){
387 Th_DeleteInterp(g.interp); g.interp = 0;
388 }
389 assert( Th_GetOutstandingMalloc()==0 ); */
390 }
391
392 /*
393 ** Convert all arguments from mbcs (or unicode) to UTF-8. Then
394 ** search g.argv for arguments "--args FILENAME". If found, then
395
+8 -3
--- src/th.c
+++ src/th.c
@@ -1878,18 +1878,20 @@
18781878
switch( pExpr->pOp->eOp ) {
18791879
case OP_MULTIPLY: iRes = iLeft*iRight; break;
18801880
case OP_DIVIDE:
18811881
if( !iRight ){
18821882
Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
1883
- return TH_ERROR;
1883
+ rc = TH_ERROR;
1884
+ goto finish;
18841885
}
18851886
iRes = iLeft/iRight;
18861887
break;
18871888
case OP_MODULUS:
18881889
if( !iRight ){
18891890
Th_ErrorMessage(interp, "Modulo by 0:", zLeft, nLeft);
1890
- return TH_ERROR;
1891
+ rc = TH_ERROR;
1892
+ goto finish;
18911893
}
18921894
iRes = iLeft%iRight;
18931895
break;
18941896
case OP_ADD: iRes = iLeft+iRight; break;
18951897
case OP_SUBTRACT: iRes = iLeft-iRight; break;
@@ -1916,11 +1918,12 @@
19161918
switch( pExpr->pOp->eOp ) {
19171919
case OP_MULTIPLY: Th_SetResultDouble(interp, fLeft*fRight); break;
19181920
case OP_DIVIDE:
19191921
if( fRight==0.0 ){
19201922
Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
1921
- return TH_ERROR;
1923
+ rc = TH_ERROR;
1924
+ goto finish;
19221925
}
19231926
Th_SetResultDouble(interp, fLeft/fRight);
19241927
break;
19251928
case OP_ADD: Th_SetResultDouble(interp, fLeft+fRight); break;
19261929
case OP_SUBTRACT: Th_SetResultDouble(interp, fLeft-fRight); break;
@@ -1942,10 +1945,12 @@
19421945
case OP_SEQ: Th_SetResultInt(interp, iEqual); break;
19431946
case OP_SNE: Th_SetResultInt(interp, !iEqual); break;
19441947
default: assert(!"Internal error");
19451948
}
19461949
}
1950
+
1951
+ finish:
19471952
19481953
Th_Free(interp, zLeft);
19491954
Th_Free(interp, zRight);
19501955
}
19511956
19521957
--- src/th.c
+++ src/th.c
@@ -1878,18 +1878,20 @@
1878 switch( pExpr->pOp->eOp ) {
1879 case OP_MULTIPLY: iRes = iLeft*iRight; break;
1880 case OP_DIVIDE:
1881 if( !iRight ){
1882 Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
1883 return TH_ERROR;
 
1884 }
1885 iRes = iLeft/iRight;
1886 break;
1887 case OP_MODULUS:
1888 if( !iRight ){
1889 Th_ErrorMessage(interp, "Modulo by 0:", zLeft, nLeft);
1890 return TH_ERROR;
 
1891 }
1892 iRes = iLeft%iRight;
1893 break;
1894 case OP_ADD: iRes = iLeft+iRight; break;
1895 case OP_SUBTRACT: iRes = iLeft-iRight; break;
@@ -1916,11 +1918,12 @@
1916 switch( pExpr->pOp->eOp ) {
1917 case OP_MULTIPLY: Th_SetResultDouble(interp, fLeft*fRight); break;
1918 case OP_DIVIDE:
1919 if( fRight==0.0 ){
1920 Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
1921 return TH_ERROR;
 
1922 }
1923 Th_SetResultDouble(interp, fLeft/fRight);
1924 break;
1925 case OP_ADD: Th_SetResultDouble(interp, fLeft+fRight); break;
1926 case OP_SUBTRACT: Th_SetResultDouble(interp, fLeft-fRight); break;
@@ -1942,10 +1945,12 @@
1942 case OP_SEQ: Th_SetResultInt(interp, iEqual); break;
1943 case OP_SNE: Th_SetResultInt(interp, !iEqual); break;
1944 default: assert(!"Internal error");
1945 }
1946 }
 
 
1947
1948 Th_Free(interp, zLeft);
1949 Th_Free(interp, zRight);
1950 }
1951
1952
--- src/th.c
+++ src/th.c
@@ -1878,18 +1878,20 @@
1878 switch( pExpr->pOp->eOp ) {
1879 case OP_MULTIPLY: iRes = iLeft*iRight; break;
1880 case OP_DIVIDE:
1881 if( !iRight ){
1882 Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
1883 rc = TH_ERROR;
1884 goto finish;
1885 }
1886 iRes = iLeft/iRight;
1887 break;
1888 case OP_MODULUS:
1889 if( !iRight ){
1890 Th_ErrorMessage(interp, "Modulo by 0:", zLeft, nLeft);
1891 rc = TH_ERROR;
1892 goto finish;
1893 }
1894 iRes = iLeft%iRight;
1895 break;
1896 case OP_ADD: iRes = iLeft+iRight; break;
1897 case OP_SUBTRACT: iRes = iLeft-iRight; break;
@@ -1916,11 +1918,12 @@
1918 switch( pExpr->pOp->eOp ) {
1919 case OP_MULTIPLY: Th_SetResultDouble(interp, fLeft*fRight); break;
1920 case OP_DIVIDE:
1921 if( fRight==0.0 ){
1922 Th_ErrorMessage(interp, "Divide by 0:", zLeft, nLeft);
1923 rc = TH_ERROR;
1924 goto finish;
1925 }
1926 Th_SetResultDouble(interp, fLeft/fRight);
1927 break;
1928 case OP_ADD: Th_SetResultDouble(interp, fLeft+fRight); break;
1929 case OP_SUBTRACT: Th_SetResultDouble(interp, fLeft-fRight); break;
@@ -1942,10 +1945,12 @@
1945 case OP_SEQ: Th_SetResultInt(interp, iEqual); break;
1946 case OP_SNE: Th_SetResultInt(interp, !iEqual); break;
1947 default: assert(!"Internal error");
1948 }
1949 }
1950
1951 finish:
1952
1953 Th_Free(interp, zLeft);
1954 Th_Free(interp, zRight);
1955 }
1956
1957
--- src/th_main.c
+++ src/th_main.c
@@ -57,10 +57,17 @@
5757
nOutstandingMalloc--;
5858
}
5959
free(p);
6060
}
6161
static Th_Vtab vtab = { xMalloc, xFree };
62
+
63
+/*
64
+** Returns the number of outstanding TH1 memory allocations.
65
+*/
66
+int Th_GetOutstandingMalloc(){
67
+ return nOutstandingMalloc;
68
+}
6269
6370
/*
6471
** Generate a TH1 trace message if debugging is enabled.
6572
*/
6673
void Th_Trace(const char *zFormat, ...){
6774
--- src/th_main.c
+++ src/th_main.c
@@ -57,10 +57,17 @@
57 nOutstandingMalloc--;
58 }
59 free(p);
60 }
61 static Th_Vtab vtab = { xMalloc, xFree };
 
 
 
 
 
 
 
62
63 /*
64 ** Generate a TH1 trace message if debugging is enabled.
65 */
66 void Th_Trace(const char *zFormat, ...){
67
--- src/th_main.c
+++ src/th_main.c
@@ -57,10 +57,17 @@
57 nOutstandingMalloc--;
58 }
59 free(p);
60 }
61 static Th_Vtab vtab = { xMalloc, xFree };
62
63 /*
64 ** Returns the number of outstanding TH1 memory allocations.
65 */
66 int Th_GetOutstandingMalloc(){
67 return nOutstandingMalloc;
68 }
69
70 /*
71 ** Generate a TH1 trace message if debugging is enabled.
72 */
73 void Th_Trace(const char *zFormat, ...){
74
--- test/th1.test
+++ test/th1.test
@@ -85,5 +85,27 @@
8585
8686
###############################################################################
8787
8888
fossil test-th-eval "expr 42.0/0.0"
8989
test th1-divide-by-zero-4 {$RESULT eq {TH_ERROR: Divide by 0: 42.0}}
90
+
91
+###############################################################################
92
+
93
+fossil test-th-eval "expr 42%0"
94
+test th1-modulus-by-zero-1 {$RESULT eq {TH_ERROR: Modulo by 0: 42}}
95
+
96
+###############################################################################
97
+
98
+fossil test-th-eval "expr 42%0.0"
99
+test th1-modulus-by-zero-2 {$RESULT eq {TH_ERROR: expected integer, got: "0.0"}}
100
+
101
+###############################################################################
102
+
103
+fossil test-th-eval "expr 42.0%0"
104
+test th1-modulus-by-zero-3 {$RESULT eq \
105
+{TH_ERROR: expected integer, got: "42.0"}}
106
+
107
+###############################################################################
108
+
109
+fossil test-th-eval "expr 42.0%0.0"
110
+test th1-modulus-by-zero-4 {$RESULT eq \
111
+{TH_ERROR: expected integer, got: "42.0"}}
90112
--- test/th1.test
+++ test/th1.test
@@ -85,5 +85,27 @@
85
86 ###############################################################################
87
88 fossil test-th-eval "expr 42.0/0.0"
89 test th1-divide-by-zero-4 {$RESULT eq {TH_ERROR: Divide by 0: 42.0}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
--- test/th1.test
+++ test/th1.test
@@ -85,5 +85,27 @@
85
86 ###############################################################################
87
88 fossil test-th-eval "expr 42.0/0.0"
89 test th1-divide-by-zero-4 {$RESULT eq {TH_ERROR: Divide by 0: 42.0}}
90
91 ###############################################################################
92
93 fossil test-th-eval "expr 42%0"
94 test th1-modulus-by-zero-1 {$RESULT eq {TH_ERROR: Modulo by 0: 42}}
95
96 ###############################################################################
97
98 fossil test-th-eval "expr 42%0.0"
99 test th1-modulus-by-zero-2 {$RESULT eq {TH_ERROR: expected integer, got: "0.0"}}
100
101 ###############################################################################
102
103 fossil test-th-eval "expr 42.0%0"
104 test th1-modulus-by-zero-3 {$RESULT eq \
105 {TH_ERROR: expected integer, got: "42.0"}}
106
107 ###############################################################################
108
109 fossil test-th-eval "expr 42.0%0.0"
110 test th1-modulus-by-zero-4 {$RESULT eq \
111 {TH_ERROR: expected integer, got: "42.0"}}
112

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button