Fossil SCM
Improve the validation of the sequence number in clone messages in the sync protocol.
Commit
295b396036097842e322aaa2a24ea8868aafd71ef5b053dba9b0395de3d8e2c4
Parent
5de7ce9a0673c99…
1 file changed
+18
-1
+18
-1
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1119,10 +1119,23 @@ | ||
| 1119 | 1119 | ** Return the TH1 code to evaluate when a ticket change is processed. |
| 1120 | 1120 | */ |
| 1121 | 1121 | const char *xfer_ticket_code(void){ |
| 1122 | 1122 | return db_get("xfer-ticket-script", 0); |
| 1123 | 1123 | } |
| 1124 | + | |
| 1125 | +/* | |
| 1126 | +** Reset the CGI content, roll back any pending db transaction, and | |
| 1127 | +** emit an "error" xfer message, which must be pre-fossilized by the | |
| 1128 | +** caller. | |
| 1129 | +*/ | |
| 1130 | +static void xfer_error(const char *zFossilizedMsg){ | |
| 1131 | + cgi_reset_content(); | |
| 1132 | + if( db_transaction_nesting_depth() > 0 ){ | |
| 1133 | + db_rollback_transaction(); | |
| 1134 | + } | |
| 1135 | + @ error %s(zFossilizedMsg) | |
| 1136 | +} | |
| 1124 | 1137 | |
| 1125 | 1138 | /* |
| 1126 | 1139 | ** Run the specified TH1 script, if any, and returns 1 on error. |
| 1127 | 1140 | */ |
| 1128 | 1141 | int xfer_run_script( |
| @@ -1461,10 +1474,14 @@ | ||
| 1461 | 1474 | int seqno, max; |
| 1462 | 1475 | if( iVers>=3 ){ |
| 1463 | 1476 | cgi_set_content_type("application/x-fossil-uncompressed"); |
| 1464 | 1477 | } |
| 1465 | 1478 | blob_is_int(&xfer.aToken[2], &seqno); |
| 1479 | + if( seqno<=0 ){ | |
| 1480 | + xfer_error("invalid\\sclone\\ssequence\\snumber"); | |
| 1481 | + return; | |
| 1482 | + } | |
| 1466 | 1483 | max = db_int(0, "SELECT max(rid) FROM blob"); |
| 1467 | 1484 | while( xfer.mxSend>(int)blob_size(xfer.pOut) && seqno<=max){ |
| 1468 | 1485 | if( time(NULL) >= xfer.maxTime ) break; |
| 1469 | 1486 | if( iVers>=3 ){ |
| 1470 | 1487 | send_compressed_file(&xfer, seqno); |
| @@ -1844,11 +1861,11 @@ | ||
| 1844 | 1861 | /* Send the server timestamp last, in case prior processing happened |
| 1845 | 1862 | ** to use up a significant fraction of our time window. |
| 1846 | 1863 | */ |
| 1847 | 1864 | zNow = db_text(0, "SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%S', 'now')"); |
| 1848 | 1865 | @ # timestamp %s(zNow) errors %d(nErr) |
| 1849 | - free(zNow); | |
| 1866 | + fossil_free(zNow); | |
| 1850 | 1867 | |
| 1851 | 1868 | db_commit_transaction(); |
| 1852 | 1869 | configure_rebuild(); |
| 1853 | 1870 | } |
| 1854 | 1871 | |
| 1855 | 1872 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1119,10 +1119,23 @@ | |
| 1119 | ** Return the TH1 code to evaluate when a ticket change is processed. |
| 1120 | */ |
| 1121 | const char *xfer_ticket_code(void){ |
| 1122 | return db_get("xfer-ticket-script", 0); |
| 1123 | } |
| 1124 | |
| 1125 | /* |
| 1126 | ** Run the specified TH1 script, if any, and returns 1 on error. |
| 1127 | */ |
| 1128 | int xfer_run_script( |
| @@ -1461,10 +1474,14 @@ | |
| 1461 | int seqno, max; |
| 1462 | if( iVers>=3 ){ |
| 1463 | cgi_set_content_type("application/x-fossil-uncompressed"); |
| 1464 | } |
| 1465 | blob_is_int(&xfer.aToken[2], &seqno); |
| 1466 | max = db_int(0, "SELECT max(rid) FROM blob"); |
| 1467 | while( xfer.mxSend>(int)blob_size(xfer.pOut) && seqno<=max){ |
| 1468 | if( time(NULL) >= xfer.maxTime ) break; |
| 1469 | if( iVers>=3 ){ |
| 1470 | send_compressed_file(&xfer, seqno); |
| @@ -1844,11 +1861,11 @@ | |
| 1844 | /* Send the server timestamp last, in case prior processing happened |
| 1845 | ** to use up a significant fraction of our time window. |
| 1846 | */ |
| 1847 | zNow = db_text(0, "SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%S', 'now')"); |
| 1848 | @ # timestamp %s(zNow) errors %d(nErr) |
| 1849 | free(zNow); |
| 1850 | |
| 1851 | db_commit_transaction(); |
| 1852 | configure_rebuild(); |
| 1853 | } |
| 1854 | |
| 1855 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1119,10 +1119,23 @@ | |
| 1119 | ** Return the TH1 code to evaluate when a ticket change is processed. |
| 1120 | */ |
| 1121 | const char *xfer_ticket_code(void){ |
| 1122 | return db_get("xfer-ticket-script", 0); |
| 1123 | } |
| 1124 | |
| 1125 | /* |
| 1126 | ** Reset the CGI content, roll back any pending db transaction, and |
| 1127 | ** emit an "error" xfer message, which must be pre-fossilized by the |
| 1128 | ** caller. |
| 1129 | */ |
| 1130 | static void xfer_error(const char *zFossilizedMsg){ |
| 1131 | cgi_reset_content(); |
| 1132 | if( db_transaction_nesting_depth() > 0 ){ |
| 1133 | db_rollback_transaction(); |
| 1134 | } |
| 1135 | @ error %s(zFossilizedMsg) |
| 1136 | } |
| 1137 | |
| 1138 | /* |
| 1139 | ** Run the specified TH1 script, if any, and returns 1 on error. |
| 1140 | */ |
| 1141 | int xfer_run_script( |
| @@ -1461,10 +1474,14 @@ | |
| 1474 | int seqno, max; |
| 1475 | if( iVers>=3 ){ |
| 1476 | cgi_set_content_type("application/x-fossil-uncompressed"); |
| 1477 | } |
| 1478 | blob_is_int(&xfer.aToken[2], &seqno); |
| 1479 | if( seqno<=0 ){ |
| 1480 | xfer_error("invalid\\sclone\\ssequence\\snumber"); |
| 1481 | return; |
| 1482 | } |
| 1483 | max = db_int(0, "SELECT max(rid) FROM blob"); |
| 1484 | while( xfer.mxSend>(int)blob_size(xfer.pOut) && seqno<=max){ |
| 1485 | if( time(NULL) >= xfer.maxTime ) break; |
| 1486 | if( iVers>=3 ){ |
| 1487 | send_compressed_file(&xfer, seqno); |
| @@ -1844,11 +1861,11 @@ | |
| 1861 | /* Send the server timestamp last, in case prior processing happened |
| 1862 | ** to use up a significant fraction of our time window. |
| 1863 | */ |
| 1864 | zNow = db_text(0, "SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%S', 'now')"); |
| 1865 | @ # timestamp %s(zNow) errors %d(nErr) |
| 1866 | fossil_free(zNow); |
| 1867 | |
| 1868 | db_commit_transaction(); |
| 1869 | configure_rebuild(); |
| 1870 | } |
| 1871 | |
| 1872 |