Fossil SCM
Improvements to command-line safety checks for Windows. Enhance the command-line argument quoting fuzzer to inject all kinds of multi-byte UTF-8 characters.
Commit
6d2e48b4cd38e0283863b88c0b5b96091c642fea3d61d2a5b4f131f86ad476a8
Parent
19f195a838ba539…
2 files changed
+25
-4
+1
-7
+25
-4
| --- src/blob.c | ||
| +++ src/blob.c | ||
| @@ -1543,21 +1543,42 @@ | ||
| 1543 | 1543 | for(j=0; j<n; j++){ |
| 1544 | 1544 | unsigned char m, k; |
| 1545 | 1545 | int rc; |
| 1546 | 1546 | unsigned char zWord[100]; |
| 1547 | 1547 | sqlite3_randomness(sizeof(m), &m); |
| 1548 | - m %= 50; | |
| 1549 | - m += 2; | |
| 1548 | + m = (m%40)+5; | |
| 1550 | 1549 | sqlite3_randomness(m, zWord); |
| 1551 | 1550 | for(k=0; k<m; k++){ |
| 1552 | 1551 | unsigned char cx = zWord[k]; |
| 1553 | 1552 | if( cx<0x20 || cx>=0x7f ){ |
| 1554 | - zWord[k] = "abcdefghijklmnopqrstuvwxyz_"[cx%27]; | |
| 1553 | + unsigned int u; | |
| 1554 | + if( cx>=0x7f ){ | |
| 1555 | + u = cx; | |
| 1556 | + }else if( cx>=0x08 ){ | |
| 1557 | + u = 0x800 + cx; | |
| 1558 | + }else{ | |
| 1559 | + u = 0x10000 + cx; | |
| 1560 | + } | |
| 1561 | + if( u<0x00080 ){ | |
| 1562 | + zWord[k] = u & 0xFF; | |
| 1563 | + }else if( u<0x00800 ){ | |
| 1564 | + zWord[k++] = 0xC0 + (u8)((u>>6)&0x1F); | |
| 1565 | + zWord[k] = 0x80 + (u8)(u & 0x3F); | |
| 1566 | + }else if( u<0x10000 ){ | |
| 1567 | + zWord[k++] = 0xE0 + (u8)((u>>12)&0x0F); | |
| 1568 | + zWord[k++] = 0x80 + (u8)((u>>6) & 0x3F); | |
| 1569 | + zWord[k] = 0x80 + (u8)(u & 0x3F); | |
| 1570 | + }else{ | |
| 1571 | + zWord[k++] = 0xF0 + (u8)((u>>18) & 0x07); | |
| 1572 | + zWord[k++] = 0x80 + (u8)((u>>12) & 0x3F); | |
| 1573 | + zWord[k++] = 0x80 + (u8)((u>>6) & 0x3F); | |
| 1574 | + zWord[k] = 0x80 + (u8)(u & 0x3F); | |
| 1575 | + } | |
| 1555 | 1576 | } |
| 1556 | 1577 | } |
| 1557 | 1578 | zWord[k] = 0; |
| 1558 | - encode16(zWord, (unsigned char*)zBuf, (int)m); | |
| 1579 | + encode16(zWord, (unsigned char*)zBuf, (int)k); | |
| 1559 | 1580 | blob_appendf(&x, "%$ test-escaped-arg --compare %s %$", |
| 1560 | 1581 | g.nameOfExe, zBuf,zWord); |
| 1561 | 1582 | rc = fossil_system(blob_str(&x)); |
| 1562 | 1583 | if( rc ) fossil_fatal("failed test (%d): %s\n", rc, blob_str(&x)); |
| 1563 | 1584 | blob_reset(&x); |
| 1564 | 1585 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -1543,21 +1543,42 @@ | |
| 1543 | for(j=0; j<n; j++){ |
| 1544 | unsigned char m, k; |
| 1545 | int rc; |
| 1546 | unsigned char zWord[100]; |
| 1547 | sqlite3_randomness(sizeof(m), &m); |
| 1548 | m %= 50; |
| 1549 | m += 2; |
| 1550 | sqlite3_randomness(m, zWord); |
| 1551 | for(k=0; k<m; k++){ |
| 1552 | unsigned char cx = zWord[k]; |
| 1553 | if( cx<0x20 || cx>=0x7f ){ |
| 1554 | zWord[k] = "abcdefghijklmnopqrstuvwxyz_"[cx%27]; |
| 1555 | } |
| 1556 | } |
| 1557 | zWord[k] = 0; |
| 1558 | encode16(zWord, (unsigned char*)zBuf, (int)m); |
| 1559 | blob_appendf(&x, "%$ test-escaped-arg --compare %s %$", |
| 1560 | g.nameOfExe, zBuf,zWord); |
| 1561 | rc = fossil_system(blob_str(&x)); |
| 1562 | if( rc ) fossil_fatal("failed test (%d): %s\n", rc, blob_str(&x)); |
| 1563 | blob_reset(&x); |
| 1564 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -1543,21 +1543,42 @@ | |
| 1543 | for(j=0; j<n; j++){ |
| 1544 | unsigned char m, k; |
| 1545 | int rc; |
| 1546 | unsigned char zWord[100]; |
| 1547 | sqlite3_randomness(sizeof(m), &m); |
| 1548 | m = (m%40)+5; |
| 1549 | sqlite3_randomness(m, zWord); |
| 1550 | for(k=0; k<m; k++){ |
| 1551 | unsigned char cx = zWord[k]; |
| 1552 | if( cx<0x20 || cx>=0x7f ){ |
| 1553 | unsigned int u; |
| 1554 | if( cx>=0x7f ){ |
| 1555 | u = cx; |
| 1556 | }else if( cx>=0x08 ){ |
| 1557 | u = 0x800 + cx; |
| 1558 | }else{ |
| 1559 | u = 0x10000 + cx; |
| 1560 | } |
| 1561 | if( u<0x00080 ){ |
| 1562 | zWord[k] = u & 0xFF; |
| 1563 | }else if( u<0x00800 ){ |
| 1564 | zWord[k++] = 0xC0 + (u8)((u>>6)&0x1F); |
| 1565 | zWord[k] = 0x80 + (u8)(u & 0x3F); |
| 1566 | }else if( u<0x10000 ){ |
| 1567 | zWord[k++] = 0xE0 + (u8)((u>>12)&0x0F); |
| 1568 | zWord[k++] = 0x80 + (u8)((u>>6) & 0x3F); |
| 1569 | zWord[k] = 0x80 + (u8)(u & 0x3F); |
| 1570 | }else{ |
| 1571 | zWord[k++] = 0xF0 + (u8)((u>>18) & 0x07); |
| 1572 | zWord[k++] = 0x80 + (u8)((u>>12) & 0x3F); |
| 1573 | zWord[k++] = 0x80 + (u8)((u>>6) & 0x3F); |
| 1574 | zWord[k] = 0x80 + (u8)(u & 0x3F); |
| 1575 | } |
| 1576 | } |
| 1577 | } |
| 1578 | zWord[k] = 0; |
| 1579 | encode16(zWord, (unsigned char*)zBuf, (int)k); |
| 1580 | blob_appendf(&x, "%$ test-escaped-arg --compare %s %$", |
| 1581 | g.nameOfExe, zBuf,zWord); |
| 1582 | rc = fossil_system(blob_str(&x)); |
| 1583 | if( rc ) fossil_fatal("failed test (%d): %s\n", rc, blob_str(&x)); |
| 1584 | blob_reset(&x); |
| 1585 |
+1
-7
| --- src/util.c | ||
| +++ src/util.c | ||
| @@ -250,26 +250,20 @@ | ||
| 250 | 250 | case '&': |
| 251 | 251 | case '\n': { |
| 252 | 252 | if( inQuote==0 && z[i+1]!=0 ) unsafe = i+1; |
| 253 | 253 | break; |
| 254 | 254 | } |
| 255 | - case '\\': { | |
| 256 | - if( z[i+1]=='"' ){ i++; } | |
| 257 | - break; | |
| 258 | - } | |
| 259 | 255 | case '"': { |
| 260 | 256 | if( inQuote==c ){ |
| 261 | 257 | inQuote = 0; |
| 262 | 258 | }else{ |
| 263 | 259 | inQuote = c; |
| 264 | 260 | } |
| 265 | 261 | break; |
| 266 | 262 | } |
| 267 | 263 | case '^': { |
| 268 | - if( z[i+1]=='"' ){ | |
| 269 | - unsafe = i+2; | |
| 270 | - }else if( z[i+1]!=0 ){ | |
| 264 | + if( !inQuote && z[i+1]!=0 ){ | |
| 271 | 265 | i++; |
| 272 | 266 | } |
| 273 | 267 | break; |
| 274 | 268 | } |
| 275 | 269 | } |
| 276 | 270 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -250,26 +250,20 @@ | |
| 250 | case '&': |
| 251 | case '\n': { |
| 252 | if( inQuote==0 && z[i+1]!=0 ) unsafe = i+1; |
| 253 | break; |
| 254 | } |
| 255 | case '\\': { |
| 256 | if( z[i+1]=='"' ){ i++; } |
| 257 | break; |
| 258 | } |
| 259 | case '"': { |
| 260 | if( inQuote==c ){ |
| 261 | inQuote = 0; |
| 262 | }else{ |
| 263 | inQuote = c; |
| 264 | } |
| 265 | break; |
| 266 | } |
| 267 | case '^': { |
| 268 | if( z[i+1]=='"' ){ |
| 269 | unsafe = i+2; |
| 270 | }else if( z[i+1]!=0 ){ |
| 271 | i++; |
| 272 | } |
| 273 | break; |
| 274 | } |
| 275 | } |
| 276 |
| --- src/util.c | |
| +++ src/util.c | |
| @@ -250,26 +250,20 @@ | |
| 250 | case '&': |
| 251 | case '\n': { |
| 252 | if( inQuote==0 && z[i+1]!=0 ) unsafe = i+1; |
| 253 | break; |
| 254 | } |
| 255 | case '"': { |
| 256 | if( inQuote==c ){ |
| 257 | inQuote = 0; |
| 258 | }else{ |
| 259 | inQuote = c; |
| 260 | } |
| 261 | break; |
| 262 | } |
| 263 | case '^': { |
| 264 | if( !inQuote && z[i+1]!=0 ){ |
| 265 | i++; |
| 266 | } |
| 267 | break; |
| 268 | } |
| 269 | } |
| 270 |