Fossil SCM
Fix assert in the TH1 expression parser reported on the mailing list.
Commit
cd64405786ee7d6ec8e06e6477090538a4d06c34
Parent
ee46563cbdc28fa…
2 files changed
+3
-4
+5
M
src/th.c
+3
-4
| --- src/th.c | ||
| +++ src/th.c | ||
| @@ -2123,11 +2123,12 @@ | ||
| 2123 | 2123 | } |
| 2124 | 2124 | |
| 2125 | 2125 | iLeft = 0; |
| 2126 | 2126 | for(jj=nToken-1; jj>=0; jj--){ |
| 2127 | 2127 | if( apToken[jj] ){ |
| 2128 | - if( apToken[jj]->pOp && apToken[jj]->pOp->iPrecedence==1 && iLeft>0 ){ | |
| 2128 | + if( apToken[jj]->pOp && apToken[jj]->pOp->iPrecedence==1 | |
| 2129 | + && iLeft>0 && ISTERM(iLeft) ){ | |
| 2129 | 2130 | apToken[jj]->pLeft = apToken[iLeft]; |
| 2130 | 2131 | apToken[jj]->pLeft->pParent = apToken[jj]; |
| 2131 | 2132 | apToken[iLeft] = 0; |
| 2132 | 2133 | } |
| 2133 | 2134 | iLeft = jj; |
| @@ -2138,13 +2139,11 @@ | ||
| 2138 | 2139 | for(jj=0; jj<nToken; jj++){ |
| 2139 | 2140 | Expr *pToken = apToken[jj]; |
| 2140 | 2141 | if( apToken[jj] ){ |
| 2141 | 2142 | if( pToken->pOp && !pToken->pLeft && pToken->pOp->iPrecedence==i ){ |
| 2142 | 2143 | int iRight = jj+1; |
| 2143 | - | |
| 2144 | - iRight = jj+1; | |
| 2145 | - for(iRight=jj+1; !apToken[iRight] && iRight<nToken; iRight++); | |
| 2144 | + for(; !apToken[iRight] && iRight<nToken; iRight++); | |
| 2146 | 2145 | if( iRight==nToken || iLeft<0 || !ISTERM(iRight) || !ISTERM(iLeft) ){ |
| 2147 | 2146 | return TH_ERROR; |
| 2148 | 2147 | } |
| 2149 | 2148 | pToken->pLeft = apToken[iLeft]; |
| 2150 | 2149 | apToken[iLeft] = 0; |
| 2151 | 2150 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -2123,11 +2123,12 @@ | |
| 2123 | } |
| 2124 | |
| 2125 | iLeft = 0; |
| 2126 | for(jj=nToken-1; jj>=0; jj--){ |
| 2127 | if( apToken[jj] ){ |
| 2128 | if( apToken[jj]->pOp && apToken[jj]->pOp->iPrecedence==1 && iLeft>0 ){ |
| 2129 | apToken[jj]->pLeft = apToken[iLeft]; |
| 2130 | apToken[jj]->pLeft->pParent = apToken[jj]; |
| 2131 | apToken[iLeft] = 0; |
| 2132 | } |
| 2133 | iLeft = jj; |
| @@ -2138,13 +2139,11 @@ | |
| 2138 | for(jj=0; jj<nToken; jj++){ |
| 2139 | Expr *pToken = apToken[jj]; |
| 2140 | if( apToken[jj] ){ |
| 2141 | if( pToken->pOp && !pToken->pLeft && pToken->pOp->iPrecedence==i ){ |
| 2142 | int iRight = jj+1; |
| 2143 | |
| 2144 | iRight = jj+1; |
| 2145 | for(iRight=jj+1; !apToken[iRight] && iRight<nToken; iRight++); |
| 2146 | if( iRight==nToken || iLeft<0 || !ISTERM(iRight) || !ISTERM(iLeft) ){ |
| 2147 | return TH_ERROR; |
| 2148 | } |
| 2149 | pToken->pLeft = apToken[iLeft]; |
| 2150 | apToken[iLeft] = 0; |
| 2151 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -2123,11 +2123,12 @@ | |
| 2123 | } |
| 2124 | |
| 2125 | iLeft = 0; |
| 2126 | for(jj=nToken-1; jj>=0; jj--){ |
| 2127 | if( apToken[jj] ){ |
| 2128 | if( apToken[jj]->pOp && apToken[jj]->pOp->iPrecedence==1 |
| 2129 | && iLeft>0 && ISTERM(iLeft) ){ |
| 2130 | apToken[jj]->pLeft = apToken[iLeft]; |
| 2131 | apToken[jj]->pLeft->pParent = apToken[jj]; |
| 2132 | apToken[iLeft] = 0; |
| 2133 | } |
| 2134 | iLeft = jj; |
| @@ -2138,13 +2139,11 @@ | |
| 2139 | for(jj=0; jj<nToken; jj++){ |
| 2140 | Expr *pToken = apToken[jj]; |
| 2141 | if( apToken[jj] ){ |
| 2142 | if( pToken->pOp && !pToken->pLeft && pToken->pOp->iPrecedence==i ){ |
| 2143 | int iRight = jj+1; |
| 2144 | for(; !apToken[iRight] && iRight<nToken; iRight++); |
| 2145 | if( iRight==nToken || iLeft<0 || !ISTERM(iRight) || !ISTERM(iLeft) ){ |
| 2146 | return TH_ERROR; |
| 2147 | } |
| 2148 | pToken->pLeft = apToken[iLeft]; |
| 2149 | apToken[iLeft] = 0; |
| 2150 |
+5
| --- test/th1.test | ||
| +++ test/th1.test | ||
| @@ -477,10 +477,15 @@ | ||
| 477 | 477 | |
| 478 | 478 | ############################################################################### |
| 479 | 479 | |
| 480 | 480 | fossil test-th-eval "expr 0+0b" |
| 481 | 481 | test th1-expr-35 {$RESULT eq {TH_ERROR: expected number, got: "0b"}} |
| 482 | + | |
| 483 | +############################################################################### | |
| 484 | + | |
| 485 | +fossil test-th-eval "expr (-1)+1" | |
| 486 | +test th1-expr-36 {$RESULT eq {0}} | |
| 482 | 487 | |
| 483 | 488 | ############################################################################### |
| 484 | 489 | |
| 485 | 490 | fossil test-th-eval "checkout 1"; # NOTE: Assumes running "in tree". |
| 486 | 491 | test th1-checkout-1 {[string length $RESULT] > 0} |
| 487 | 492 |
| --- test/th1.test | |
| +++ test/th1.test | |
| @@ -477,10 +477,15 @@ | |
| 477 | |
| 478 | ############################################################################### |
| 479 | |
| 480 | fossil test-th-eval "expr 0+0b" |
| 481 | test th1-expr-35 {$RESULT eq {TH_ERROR: expected number, got: "0b"}} |
| 482 | |
| 483 | ############################################################################### |
| 484 | |
| 485 | fossil test-th-eval "checkout 1"; # NOTE: Assumes running "in tree". |
| 486 | test th1-checkout-1 {[string length $RESULT] > 0} |
| 487 |
| --- test/th1.test | |
| +++ test/th1.test | |
| @@ -477,10 +477,15 @@ | |
| 477 | |
| 478 | ############################################################################### |
| 479 | |
| 480 | fossil test-th-eval "expr 0+0b" |
| 481 | test th1-expr-35 {$RESULT eq {TH_ERROR: expected number, got: "0b"}} |
| 482 | |
| 483 | ############################################################################### |
| 484 | |
| 485 | fossil test-th-eval "expr (-1)+1" |
| 486 | test th1-expr-36 {$RESULT eq {0}} |
| 487 | |
| 488 | ############################################################################### |
| 489 | |
| 490 | fossil test-th-eval "checkout 1"; # NOTE: Assumes running "in tree". |
| 491 | test th1-checkout-1 {[string length $RESULT] > 0} |
| 492 |