Fossil SCM

Make sure manifest_crosslink() resets its input blob and that callers know this and do not attempt to reuse that blob.

drh 2011-02-17 20:44 trunk
Commit d22519e500b37a55a1dcb34a2bb95fbb81e26246
--- src/attach.c
+++ src/attach.c
@@ -264,10 +264,11 @@
264264
blob_appendf(&manifest, "U %F\n", g.zLogin ? g.zLogin : "nobody");
265265
md5sum_blob(&manifest, &cksum);
266266
blob_appendf(&manifest, "Z %b\n", &cksum);
267267
rid = content_put(&manifest, 0, 0, 0);
268268
manifest_crosslink(rid, &manifest);
269
+ assert( blob_is_reset(&manifest) );
269270
db_end_transaction(0);
270271
cgi_redirect(zFrom);
271272
}
272273
style_header("Add Attachment");
273274
@ <h2>Add Attachment To %s(zTargetType)</h2>
274275
--- src/attach.c
+++ src/attach.c
@@ -264,10 +264,11 @@
264 blob_appendf(&manifest, "U %F\n", g.zLogin ? g.zLogin : "nobody");
265 md5sum_blob(&manifest, &cksum);
266 blob_appendf(&manifest, "Z %b\n", &cksum);
267 rid = content_put(&manifest, 0, 0, 0);
268 manifest_crosslink(rid, &manifest);
 
269 db_end_transaction(0);
270 cgi_redirect(zFrom);
271 }
272 style_header("Add Attachment");
273 @ <h2>Add Attachment To %s(zTargetType)</h2>
274
--- src/attach.c
+++ src/attach.c
@@ -264,10 +264,11 @@
264 blob_appendf(&manifest, "U %F\n", g.zLogin ? g.zLogin : "nobody");
265 md5sum_blob(&manifest, &cksum);
266 blob_appendf(&manifest, "Z %b\n", &cksum);
267 rid = content_put(&manifest, 0, 0, 0);
268 manifest_crosslink(rid, &manifest);
269 assert( blob_is_reset(&manifest) );
270 db_end_transaction(0);
271 cgi_redirect(zFrom);
272 }
273 style_header("Add Attachment");
274 @ <h2>Add Attachment To %s(zTargetType)</h2>
275
+27 -9
--- src/blob.c
+++ src/blob.c
@@ -60,17 +60,22 @@
6060
#define blob_is_init(x) \
6161
assert((x)->xRealloc==blobReallocMalloc || (x)->xRealloc==blobReallocStatic)
6262
6363
/*
6464
** Make sure a blob does not contain malloced memory.
65
+**
66
+** This might fail if we are unlucky and x is uninitialized. For that
67
+** reason it should only be used locally for debugging. Leave it turned
68
+** off for production.
6569
*/
6670
#if 0 /* Enable for debugging only */
67
-#define blob_is_reset(x) \
68
- assert((x)->xRealloc!=blobReallocMalloc || (x)->nAlloc==0)
71
+#define assert_blob_is_reset(x) assert(blob_is_reset(x))
6972
#else
70
-#define blob_is_reset(x)
73
+#define assert_blob_is_reset(x)
7174
#endif
75
+
76
+
7277
7378
/*
7479
** We find that the built-in isspace() function does not work for
7580
** some international character sets. So here is a substitute.
7681
*/
@@ -178,16 +183,29 @@
178183
void blob_reset(Blob *pBlob){
179184
blob_is_init(pBlob);
180185
pBlob->xRealloc(pBlob, 0);
181186
}
182187
188
+
189
+/*
190
+** Return true if the blob has been zeroed - in other words if it contains
191
+** no malloced memory. This only works reliably if the blob has been
192
+** initialized - it can return a false negative on an uninitialized blob.
193
+*/
194
+int blob_is_reset(Blob *pBlob){
195
+ if( pBlob==0 ) return 1;
196
+ if( pBlob->nUsed ) return 0;
197
+ if( pBlob->xRealloc==blobReallocMalloc && pBlob->nAlloc ) return 0;
198
+ return 1;
199
+}
200
+
183201
/*
184202
** Initialize a blob to a string or byte-array constant of a specified length.
185203
** Any prior data in the blob is discarded.
186204
*/
187205
void blob_init(Blob *pBlob, const char *zData, int size){
188
- blob_is_reset(pBlob);
206
+ assert_blob_is_reset(pBlob);
189207
if( zData==0 ){
190208
*pBlob = empty_blob;
191209
}else{
192210
if( size<=0 ) size = strlen(zData);
193211
pBlob->nUsed = pBlob->nAlloc = size;
@@ -208,11 +226,11 @@
208226
/*
209227
** Initialize a blob to an empty string.
210228
*/
211229
void blob_zero(Blob *pBlob){
212230
static const char zEmpty[] = "";
213
- blob_is_reset(pBlob);
231
+ assert_blob_is_reset(pBlob);
214232
pBlob->nUsed = 0;
215233
pBlob->nAlloc = 1;
216234
pBlob->aData = (char*)zEmpty;
217235
pBlob->iCursor = 0;
218236
pBlob->xRealloc = blobReallocStatic;
@@ -357,11 +375,11 @@
357375
**
358376
** After this call completes, pTo will be an ephemeral blob.
359377
*/
360378
int blob_extract(Blob *pFrom, int N, Blob *pTo){
361379
blob_is_init(pFrom);
362
- blob_is_reset(pTo);
380
+ assert_blob_is_reset(pTo);
363381
if( pFrom->iCursor + N > pFrom->nUsed ){
364382
N = pFrom->nUsed - pFrom->iCursor;
365383
if( N<=0 ){
366384
blob_zero(pTo);
367385
return 0;
@@ -735,11 +753,11 @@
735753
outBuf[3] = nIn & 0xff;
736754
nOut2 = (long int)nOut;
737755
compress(&outBuf[4], &nOut2,
738756
(unsigned char*)blob_buffer(pIn), blob_size(pIn));
739757
if( pOut==pIn ) blob_reset(pOut);
740
- blob_is_reset(pOut);
758
+ assert_blob_is_reset(pOut);
741759
*pOut = temp;
742760
blob_resize(pOut, nOut2+4);
743761
}
744762
745763
/*
@@ -788,11 +806,11 @@
788806
deflate(&stream, Z_FINISH);
789807
blob_resize(&temp, stream.total_out + 4);
790808
deflateEnd(&stream);
791809
if( pOut==pIn1 ) blob_reset(pOut);
792810
if( pOut==pIn2 ) blob_reset(pOut);
793
- blob_is_reset(pOut);
811
+ assert_blob_is_reset(pOut);
794812
*pOut = temp;
795813
}
796814
797815
/*
798816
** COMMAND: test-compress-2
@@ -833,11 +851,11 @@
833851
blob_reset(&temp);
834852
return 1;
835853
}
836854
blob_resize(&temp, nOut2);
837855
if( pOut==pIn ) blob_reset(pOut);
838
- blob_is_reset(pOut);
856
+ assert_blob_is_reset(pOut);
839857
*pOut = temp;
840858
return 0;
841859
}
842860
843861
/*
844862
--- src/blob.c
+++ src/blob.c
@@ -60,17 +60,22 @@
60 #define blob_is_init(x) \
61 assert((x)->xRealloc==blobReallocMalloc || (x)->xRealloc==blobReallocStatic)
62
63 /*
64 ** Make sure a blob does not contain malloced memory.
 
 
 
 
65 */
66 #if 0 /* Enable for debugging only */
67 #define blob_is_reset(x) \
68 assert((x)->xRealloc!=blobReallocMalloc || (x)->nAlloc==0)
69 #else
70 #define blob_is_reset(x)
71 #endif
 
 
72
73 /*
74 ** We find that the built-in isspace() function does not work for
75 ** some international character sets. So here is a substitute.
76 */
@@ -178,16 +183,29 @@
178 void blob_reset(Blob *pBlob){
179 blob_is_init(pBlob);
180 pBlob->xRealloc(pBlob, 0);
181 }
182
 
 
 
 
 
 
 
 
 
 
 
 
 
183 /*
184 ** Initialize a blob to a string or byte-array constant of a specified length.
185 ** Any prior data in the blob is discarded.
186 */
187 void blob_init(Blob *pBlob, const char *zData, int size){
188 blob_is_reset(pBlob);
189 if( zData==0 ){
190 *pBlob = empty_blob;
191 }else{
192 if( size<=0 ) size = strlen(zData);
193 pBlob->nUsed = pBlob->nAlloc = size;
@@ -208,11 +226,11 @@
208 /*
209 ** Initialize a blob to an empty string.
210 */
211 void blob_zero(Blob *pBlob){
212 static const char zEmpty[] = "";
213 blob_is_reset(pBlob);
214 pBlob->nUsed = 0;
215 pBlob->nAlloc = 1;
216 pBlob->aData = (char*)zEmpty;
217 pBlob->iCursor = 0;
218 pBlob->xRealloc = blobReallocStatic;
@@ -357,11 +375,11 @@
357 **
358 ** After this call completes, pTo will be an ephemeral blob.
359 */
360 int blob_extract(Blob *pFrom, int N, Blob *pTo){
361 blob_is_init(pFrom);
362 blob_is_reset(pTo);
363 if( pFrom->iCursor + N > pFrom->nUsed ){
364 N = pFrom->nUsed - pFrom->iCursor;
365 if( N<=0 ){
366 blob_zero(pTo);
367 return 0;
@@ -735,11 +753,11 @@
735 outBuf[3] = nIn & 0xff;
736 nOut2 = (long int)nOut;
737 compress(&outBuf[4], &nOut2,
738 (unsigned char*)blob_buffer(pIn), blob_size(pIn));
739 if( pOut==pIn ) blob_reset(pOut);
740 blob_is_reset(pOut);
741 *pOut = temp;
742 blob_resize(pOut, nOut2+4);
743 }
744
745 /*
@@ -788,11 +806,11 @@
788 deflate(&stream, Z_FINISH);
789 blob_resize(&temp, stream.total_out + 4);
790 deflateEnd(&stream);
791 if( pOut==pIn1 ) blob_reset(pOut);
792 if( pOut==pIn2 ) blob_reset(pOut);
793 blob_is_reset(pOut);
794 *pOut = temp;
795 }
796
797 /*
798 ** COMMAND: test-compress-2
@@ -833,11 +851,11 @@
833 blob_reset(&temp);
834 return 1;
835 }
836 blob_resize(&temp, nOut2);
837 if( pOut==pIn ) blob_reset(pOut);
838 blob_is_reset(pOut);
839 *pOut = temp;
840 return 0;
841 }
842
843 /*
844
--- src/blob.c
+++ src/blob.c
@@ -60,17 +60,22 @@
60 #define blob_is_init(x) \
61 assert((x)->xRealloc==blobReallocMalloc || (x)->xRealloc==blobReallocStatic)
62
63 /*
64 ** Make sure a blob does not contain malloced memory.
65 **
66 ** This might fail if we are unlucky and x is uninitialized. For that
67 ** reason it should only be used locally for debugging. Leave it turned
68 ** off for production.
69 */
70 #if 0 /* Enable for debugging only */
71 #define assert_blob_is_reset(x) assert(blob_is_reset(x))
 
72 #else
73 #define assert_blob_is_reset(x)
74 #endif
75
76
77
78 /*
79 ** We find that the built-in isspace() function does not work for
80 ** some international character sets. So here is a substitute.
81 */
@@ -178,16 +183,29 @@
183 void blob_reset(Blob *pBlob){
184 blob_is_init(pBlob);
185 pBlob->xRealloc(pBlob, 0);
186 }
187
188
189 /*
190 ** Return true if the blob has been zeroed - in other words if it contains
191 ** no malloced memory. This only works reliably if the blob has been
192 ** initialized - it can return a false negative on an uninitialized blob.
193 */
194 int blob_is_reset(Blob *pBlob){
195 if( pBlob==0 ) return 1;
196 if( pBlob->nUsed ) return 0;
197 if( pBlob->xRealloc==blobReallocMalloc && pBlob->nAlloc ) return 0;
198 return 1;
199 }
200
201 /*
202 ** Initialize a blob to a string or byte-array constant of a specified length.
203 ** Any prior data in the blob is discarded.
204 */
205 void blob_init(Blob *pBlob, const char *zData, int size){
206 assert_blob_is_reset(pBlob);
207 if( zData==0 ){
208 *pBlob = empty_blob;
209 }else{
210 if( size<=0 ) size = strlen(zData);
211 pBlob->nUsed = pBlob->nAlloc = size;
@@ -208,11 +226,11 @@
226 /*
227 ** Initialize a blob to an empty string.
228 */
229 void blob_zero(Blob *pBlob){
230 static const char zEmpty[] = "";
231 assert_blob_is_reset(pBlob);
232 pBlob->nUsed = 0;
233 pBlob->nAlloc = 1;
234 pBlob->aData = (char*)zEmpty;
235 pBlob->iCursor = 0;
236 pBlob->xRealloc = blobReallocStatic;
@@ -357,11 +375,11 @@
375 **
376 ** After this call completes, pTo will be an ephemeral blob.
377 */
378 int blob_extract(Blob *pFrom, int N, Blob *pTo){
379 blob_is_init(pFrom);
380 assert_blob_is_reset(pTo);
381 if( pFrom->iCursor + N > pFrom->nUsed ){
382 N = pFrom->nUsed - pFrom->iCursor;
383 if( N<=0 ){
384 blob_zero(pTo);
385 return 0;
@@ -735,11 +753,11 @@
753 outBuf[3] = nIn & 0xff;
754 nOut2 = (long int)nOut;
755 compress(&outBuf[4], &nOut2,
756 (unsigned char*)blob_buffer(pIn), blob_size(pIn));
757 if( pOut==pIn ) blob_reset(pOut);
758 assert_blob_is_reset(pOut);
759 *pOut = temp;
760 blob_resize(pOut, nOut2+4);
761 }
762
763 /*
@@ -788,11 +806,11 @@
806 deflate(&stream, Z_FINISH);
807 blob_resize(&temp, stream.total_out + 4);
808 deflateEnd(&stream);
809 if( pOut==pIn1 ) blob_reset(pOut);
810 if( pOut==pIn2 ) blob_reset(pOut);
811 assert_blob_is_reset(pOut);
812 *pOut = temp;
813 }
814
815 /*
816 ** COMMAND: test-compress-2
@@ -833,11 +851,11 @@
851 blob_reset(&temp);
852 return 1;
853 }
854 blob_resize(&temp, nOut2);
855 if( pOut==pIn ) blob_reset(pOut);
856 assert_blob_is_reset(pOut);
857 *pOut = temp;
858 return 0;
859 }
860
861 /*
862
--- src/branch.c
+++ src/branch.c
@@ -144,10 +144,11 @@
144144
}
145145
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
146146
if( manifest_crosslink(brid, &branch)==0 ){
147147
fossil_panic("unable to install new manifest");
148148
}
149
+ assert( blob_is_reset(&branch) );
149150
content_deltify(rootid, brid, 0);
150151
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
151152
printf("New branch: %s\n", zUuid);
152153
if( g.argc==3 ){
153154
printf(
154155
--- src/branch.c
+++ src/branch.c
@@ -144,10 +144,11 @@
144 }
145 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
146 if( manifest_crosslink(brid, &branch)==0 ){
147 fossil_panic("unable to install new manifest");
148 }
 
149 content_deltify(rootid, brid, 0);
150 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
151 printf("New branch: %s\n", zUuid);
152 if( g.argc==3 ){
153 printf(
154
--- src/branch.c
+++ src/branch.c
@@ -144,10 +144,11 @@
144 }
145 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
146 if( manifest_crosslink(brid, &branch)==0 ){
147 fossil_panic("unable to install new manifest");
148 }
149 assert( blob_is_reset(&branch) );
150 content_deltify(rootid, brid, 0);
151 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid);
152 printf("New branch: %s\n", zUuid);
153 if( g.argc==3 ){
154 printf(
155
--- src/checkin.c
+++ src/checkin.c
@@ -1092,10 +1092,11 @@
10921092
if( nvid==0 ){
10931093
fossil_panic("trouble committing manifest: %s", g.zErrMsg);
10941094
}
10951095
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
10961096
manifest_crosslink(nvid, &manifest);
1097
+ assert( blob_is_reset(&manifest) );
10971098
content_deltify(vid, nvid, 0);
10981099
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
10991100
printf("New_Version: %s\n", zUuid);
11001101
if( outputManifest ){
11011102
zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
11021103
--- src/checkin.c
+++ src/checkin.c
@@ -1092,10 +1092,11 @@
1092 if( nvid==0 ){
1093 fossil_panic("trouble committing manifest: %s", g.zErrMsg);
1094 }
1095 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
1096 manifest_crosslink(nvid, &manifest);
 
1097 content_deltify(vid, nvid, 0);
1098 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
1099 printf("New_Version: %s\n", zUuid);
1100 if( outputManifest ){
1101 zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
1102
--- src/checkin.c
+++ src/checkin.c
@@ -1092,10 +1092,11 @@
1092 if( nvid==0 ){
1093 fossil_panic("trouble committing manifest: %s", g.zErrMsg);
1094 }
1095 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
1096 manifest_crosslink(nvid, &manifest);
1097 assert( blob_is_reset(&manifest) );
1098 content_deltify(vid, nvid, 0);
1099 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
1100 printf("New_Version: %s\n", zUuid);
1101 if( outputManifest ){
1102 zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
1103
+10 -3
--- src/content.c
+++ src/content.c
@@ -71,11 +71,14 @@
7171
contentCache.a[mn] = contentCache.a[contentCache.n];
7272
}
7373
}
7474
7575
/*
76
-** Add an entry to the content cache
76
+** Add an entry to the content cache.
77
+**
78
+** This routines hands responsibility for the artifact over to the cache.
79
+** The cache will deallocate memory when it has finished with it.
7780
*/
7881
void content_cache_insert(int rid, Blob *pBlob){
7982
struct cacheLine *p;
8083
if( contentCache.n>500 || contentCache.szTotal>50000000 ){
8184
content_cache_expire_oldest();
@@ -361,11 +364,11 @@
361364
362365
/* Parse the object rid itself */
363366
if( linkFlag ){
364367
content_get(rid, &content);
365368
manifest_crosslink(rid, &content);
366
- blob_reset(&content);
369
+ assert( blob_is_reset(&content) );
367370
}
368371
369372
/* Parse all delta-manifests that depend on baseline-manifest rid */
370373
db_prepare(&q, "SELECT rid FROM orphan WHERE baseline=%d", rid);
371374
while( db_step(&q)==SQLITE_ROW ){
@@ -378,11 +381,11 @@
378381
}
379382
db_finalize(&q);
380383
for(i=0; i<nChildUsed; i++){
381384
content_get(aChild[i], &content);
382385
manifest_crosslink(aChild[i], &content);
383
- blob_reset(&content);
386
+ assert( blob_is_reset(&content) );
384387
}
385388
if( nChildUsed ){
386389
db_multi_exec("DELETE FROM orphan WHERE baseline=%d", rid);
387390
}
388391
@@ -437,10 +440,14 @@
437440
** specified then zUuid must always be specified. If srcId is zero,
438441
** and zUuid is zero then the correct zUuid is computed from pBlob.
439442
**
440443
** If the record already exists but is a phantom, the pBlob content
441444
** is inserted and the phatom becomes a real record.
445
+**
446
+** The original content of pBlob is not disturbed. The caller continues
447
+** to be responsible for pBlob. This routine does *not* take over
448
+** responsiblity for freeing pBlob.
442449
*/
443450
int content_put(Blob *pBlob, const char *zUuid, int srcId, int nBlob){
444451
int size;
445452
int rid;
446453
Stmt s1;
447454
--- src/content.c
+++ src/content.c
@@ -71,11 +71,14 @@
71 contentCache.a[mn] = contentCache.a[contentCache.n];
72 }
73 }
74
75 /*
76 ** Add an entry to the content cache
 
 
 
77 */
78 void content_cache_insert(int rid, Blob *pBlob){
79 struct cacheLine *p;
80 if( contentCache.n>500 || contentCache.szTotal>50000000 ){
81 content_cache_expire_oldest();
@@ -361,11 +364,11 @@
361
362 /* Parse the object rid itself */
363 if( linkFlag ){
364 content_get(rid, &content);
365 manifest_crosslink(rid, &content);
366 blob_reset(&content);
367 }
368
369 /* Parse all delta-manifests that depend on baseline-manifest rid */
370 db_prepare(&q, "SELECT rid FROM orphan WHERE baseline=%d", rid);
371 while( db_step(&q)==SQLITE_ROW ){
@@ -378,11 +381,11 @@
378 }
379 db_finalize(&q);
380 for(i=0; i<nChildUsed; i++){
381 content_get(aChild[i], &content);
382 manifest_crosslink(aChild[i], &content);
383 blob_reset(&content);
384 }
385 if( nChildUsed ){
386 db_multi_exec("DELETE FROM orphan WHERE baseline=%d", rid);
387 }
388
@@ -437,10 +440,14 @@
437 ** specified then zUuid must always be specified. If srcId is zero,
438 ** and zUuid is zero then the correct zUuid is computed from pBlob.
439 **
440 ** If the record already exists but is a phantom, the pBlob content
441 ** is inserted and the phatom becomes a real record.
 
 
 
 
442 */
443 int content_put(Blob *pBlob, const char *zUuid, int srcId, int nBlob){
444 int size;
445 int rid;
446 Stmt s1;
447
--- src/content.c
+++ src/content.c
@@ -71,11 +71,14 @@
71 contentCache.a[mn] = contentCache.a[contentCache.n];
72 }
73 }
74
75 /*
76 ** Add an entry to the content cache.
77 **
78 ** This routines hands responsibility for the artifact over to the cache.
79 ** The cache will deallocate memory when it has finished with it.
80 */
81 void content_cache_insert(int rid, Blob *pBlob){
82 struct cacheLine *p;
83 if( contentCache.n>500 || contentCache.szTotal>50000000 ){
84 content_cache_expire_oldest();
@@ -361,11 +364,11 @@
364
365 /* Parse the object rid itself */
366 if( linkFlag ){
367 content_get(rid, &content);
368 manifest_crosslink(rid, &content);
369 assert( blob_is_reset(&content) );
370 }
371
372 /* Parse all delta-manifests that depend on baseline-manifest rid */
373 db_prepare(&q, "SELECT rid FROM orphan WHERE baseline=%d", rid);
374 while( db_step(&q)==SQLITE_ROW ){
@@ -378,11 +381,11 @@
381 }
382 db_finalize(&q);
383 for(i=0; i<nChildUsed; i++){
384 content_get(aChild[i], &content);
385 manifest_crosslink(aChild[i], &content);
386 assert( blob_is_reset(&content) );
387 }
388 if( nChildUsed ){
389 db_multi_exec("DELETE FROM orphan WHERE baseline=%d", rid);
390 }
391
@@ -437,10 +440,14 @@
440 ** specified then zUuid must always be specified. If srcId is zero,
441 ** and zUuid is zero then the correct zUuid is computed from pBlob.
442 **
443 ** If the record already exists but is a phantom, the pBlob content
444 ** is inserted and the phatom becomes a real record.
445 **
446 ** The original content of pBlob is not disturbed. The caller continues
447 ** to be responsible for pBlob. This routine does *not* take over
448 ** responsiblity for freeing pBlob.
449 */
450 int content_put(Blob *pBlob, const char *zUuid, int srcId, int nBlob){
451 int size;
452 int rid;
453 Stmt s1;
454
+1 -1
--- src/event.c
+++ src/event.c
@@ -346,11 +346,11 @@
346346
blob_appendf(&event, "Z %b\n", &cksum);
347347
blob_reset(&cksum);
348348
nrid = content_put(&event, 0, 0, 0);
349349
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
350350
manifest_crosslink(nrid, &event);
351
- blob_reset(&event);
351
+ assert( blob_is_reset(&event) );
352352
content_deltify(rid, nrid, 0);
353353
db_end_transaction(0);
354354
cgi_redirectf("event?name=%T", zEventId);
355355
}
356356
if( P("cancel")!=0 ){
357357
--- src/event.c
+++ src/event.c
@@ -346,11 +346,11 @@
346 blob_appendf(&event, "Z %b\n", &cksum);
347 blob_reset(&cksum);
348 nrid = content_put(&event, 0, 0, 0);
349 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
350 manifest_crosslink(nrid, &event);
351 blob_reset(&event);
352 content_deltify(rid, nrid, 0);
353 db_end_transaction(0);
354 cgi_redirectf("event?name=%T", zEventId);
355 }
356 if( P("cancel")!=0 ){
357
--- src/event.c
+++ src/event.c
@@ -346,11 +346,11 @@
346 blob_appendf(&event, "Z %b\n", &cksum);
347 blob_reset(&cksum);
348 nrid = content_put(&event, 0, 0, 0);
349 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
350 manifest_crosslink(nrid, &event);
351 assert( blob_is_reset(&event) );
352 content_deltify(rid, nrid, 0);
353 db_end_transaction(0);
354 cgi_redirectf("event?name=%T", zEventId);
355 }
356 if( P("cancel")!=0 ){
357
+1
--- src/info.c
+++ src/info.c
@@ -1556,10 +1556,11 @@
15561556
blob_appendf(&ctrl, "Z %b\n", &cksum);
15571557
db_begin_transaction();
15581558
g.markPrivate = content_is_private(rid);
15591559
nrid = content_put(&ctrl, 0, 0, 0);
15601560
manifest_crosslink(nrid, &ctrl);
1561
+ assert( blob_is_reset(&ctrl) );
15611562
db_end_transaction(0);
15621563
}
15631564
cgi_redirectf("ci?name=%s", zUuid);
15641565
}
15651566
blob_zero(&comment);
15661567
--- src/info.c
+++ src/info.c
@@ -1556,10 +1556,11 @@
1556 blob_appendf(&ctrl, "Z %b\n", &cksum);
1557 db_begin_transaction();
1558 g.markPrivate = content_is_private(rid);
1559 nrid = content_put(&ctrl, 0, 0, 0);
1560 manifest_crosslink(nrid, &ctrl);
 
1561 db_end_transaction(0);
1562 }
1563 cgi_redirectf("ci?name=%s", zUuid);
1564 }
1565 blob_zero(&comment);
1566
--- src/info.c
+++ src/info.c
@@ -1556,10 +1556,11 @@
1556 blob_appendf(&ctrl, "Z %b\n", &cksum);
1557 db_begin_transaction();
1558 g.markPrivate = content_is_private(rid);
1559 nrid = content_put(&ctrl, 0, 0, 0);
1560 manifest_crosslink(nrid, &ctrl);
1561 assert( blob_is_reset(&ctrl) );
1562 db_end_transaction(0);
1563 }
1564 cgi_redirectf("ci?name=%s", zUuid);
1565 }
1566 blob_zero(&comment);
1567
--- src/manifest.c
+++ src/manifest.c
@@ -122,10 +122,11 @@
122122
free(p->azParent);
123123
free(p->azCChild);
124124
free(p->aTag);
125125
free(p->aField);
126126
if( p->pBaseline ) manifest_destroy(p->pBaseline);
127
+ memset(p, 0, sizeof(*p));
127128
fossil_free(p);
128129
}
129130
}
130131
131132
/*
@@ -1432,10 +1433,12 @@
14321433
** in the auxiliary tables of the database in order to crosslink the
14331434
** artifact.
14341435
**
14351436
** If global variable g.xlinkClusterOnly is true, then ignore all
14361437
** control artifacts other than clusters.
1438
+**
1439
+** This routine always resets the pContent blob before returning.
14371440
**
14381441
** Historical note: This routine original processed manifests only.
14391442
** Processing for other control artifacts was added later. The name
14401443
** of the routine, "manifest_crosslink", and the name of this source
14411444
** file, is a legacy of its original use.
@@ -1447,18 +1450,21 @@
14471450
int parentid = 0;
14481451
14491452
if( (p = manifest_cache_find(rid))!=0 ){
14501453
blob_reset(pContent);
14511454
}else if( (p = manifest_parse(pContent, rid))==0 ){
1455
+ assert( blob_is_reset(pContent) || pContent==0 );
14521456
return 0;
14531457
}
14541458
if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
14551459
manifest_destroy(p);
1460
+ assert( blob_is_reset(pContent) );
14561461
return 0;
14571462
}
14581463
if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
14591464
manifest_destroy(p);
1465
+ assert( blob_is_reset(pContent) );
14601466
return 0;
14611467
}
14621468
db_begin_transaction();
14631469
if( p->type==CFTYPE_MANIFEST ){
14641470
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
@@ -1712,7 +1718,8 @@
17121718
if( p->type==CFTYPE_MANIFEST ){
17131719
manifest_cache_insert(p);
17141720
}else{
17151721
manifest_destroy(p);
17161722
}
1723
+ assert( blob_is_reset(pContent) );
17171724
return 1;
17181725
}
17191726
--- src/manifest.c
+++ src/manifest.c
@@ -122,10 +122,11 @@
122 free(p->azParent);
123 free(p->azCChild);
124 free(p->aTag);
125 free(p->aField);
126 if( p->pBaseline ) manifest_destroy(p->pBaseline);
 
127 fossil_free(p);
128 }
129 }
130
131 /*
@@ -1432,10 +1433,12 @@
1432 ** in the auxiliary tables of the database in order to crosslink the
1433 ** artifact.
1434 **
1435 ** If global variable g.xlinkClusterOnly is true, then ignore all
1436 ** control artifacts other than clusters.
 
 
1437 **
1438 ** Historical note: This routine original processed manifests only.
1439 ** Processing for other control artifacts was added later. The name
1440 ** of the routine, "manifest_crosslink", and the name of this source
1441 ** file, is a legacy of its original use.
@@ -1447,18 +1450,21 @@
1447 int parentid = 0;
1448
1449 if( (p = manifest_cache_find(rid))!=0 ){
1450 blob_reset(pContent);
1451 }else if( (p = manifest_parse(pContent, rid))==0 ){
 
1452 return 0;
1453 }
1454 if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
1455 manifest_destroy(p);
 
1456 return 0;
1457 }
1458 if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
1459 manifest_destroy(p);
 
1460 return 0;
1461 }
1462 db_begin_transaction();
1463 if( p->type==CFTYPE_MANIFEST ){
1464 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
@@ -1712,7 +1718,8 @@
1712 if( p->type==CFTYPE_MANIFEST ){
1713 manifest_cache_insert(p);
1714 }else{
1715 manifest_destroy(p);
1716 }
 
1717 return 1;
1718 }
1719
--- src/manifest.c
+++ src/manifest.c
@@ -122,10 +122,11 @@
122 free(p->azParent);
123 free(p->azCChild);
124 free(p->aTag);
125 free(p->aField);
126 if( p->pBaseline ) manifest_destroy(p->pBaseline);
127 memset(p, 0, sizeof(*p));
128 fossil_free(p);
129 }
130 }
131
132 /*
@@ -1432,10 +1433,12 @@
1433 ** in the auxiliary tables of the database in order to crosslink the
1434 ** artifact.
1435 **
1436 ** If global variable g.xlinkClusterOnly is true, then ignore all
1437 ** control artifacts other than clusters.
1438 **
1439 ** This routine always resets the pContent blob before returning.
1440 **
1441 ** Historical note: This routine original processed manifests only.
1442 ** Processing for other control artifacts was added later. The name
1443 ** of the routine, "manifest_crosslink", and the name of this source
1444 ** file, is a legacy of its original use.
@@ -1447,18 +1450,21 @@
1450 int parentid = 0;
1451
1452 if( (p = manifest_cache_find(rid))!=0 ){
1453 blob_reset(pContent);
1454 }else if( (p = manifest_parse(pContent, rid))==0 ){
1455 assert( blob_is_reset(pContent) || pContent==0 );
1456 return 0;
1457 }
1458 if( g.xlinkClusterOnly && p->type!=CFTYPE_CLUSTER ){
1459 manifest_destroy(p);
1460 assert( blob_is_reset(pContent) );
1461 return 0;
1462 }
1463 if( p->type==CFTYPE_MANIFEST && fetch_baseline(p, 0) ){
1464 manifest_destroy(p);
1465 assert( blob_is_reset(pContent) );
1466 return 0;
1467 }
1468 db_begin_transaction();
1469 if( p->type==CFTYPE_MANIFEST ){
1470 if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
@@ -1712,7 +1718,8 @@
1718 if( p->type==CFTYPE_MANIFEST ){
1719 manifest_cache_insert(p);
1720 }else{
1721 manifest_destroy(p);
1722 }
1723 assert( blob_is_reset(pContent) );
1724 return 1;
1725 }
1726
+2 -1
--- src/rebuild.c
+++ src/rebuild.c
@@ -174,12 +174,13 @@
174174
char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
175175
char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
176176
blob_write_to_file(pUse,zFile);
177177
free(zFile);
178178
free(zUuid);
179
+ blob_reset(pUse);
179180
}
180
- blob_reset(pUse);
181
+ assert( blob_is_reset(pUse) );
181182
rebuild_step_done(rid);
182183
183184
/* Call all children recursively */
184185
rid = 0;
185186
for(cid=bag_first(&children), i=1; cid; cid=bag_next(&children, cid), i++){
186187
--- src/rebuild.c
+++ src/rebuild.c
@@ -174,12 +174,13 @@
174 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
175 char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
176 blob_write_to_file(pUse,zFile);
177 free(zFile);
178 free(zUuid);
 
179 }
180 blob_reset(pUse);
181 rebuild_step_done(rid);
182
183 /* Call all children recursively */
184 rid = 0;
185 for(cid=bag_first(&children), i=1; cid; cid=bag_next(&children, cid), i++){
186
--- src/rebuild.c
+++ src/rebuild.c
@@ -174,12 +174,13 @@
174 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
175 char *zFile = mprintf(zFNameFormat, zUuid, zUuid+prefixLength);
176 blob_write_to_file(pUse,zFile);
177 free(zFile);
178 free(zUuid);
179 blob_reset(pUse);
180 }
181 assert( blob_is_reset(pUse) );
182 rebuild_step_done(rid);
183
184 /* Call all children recursively */
185 rid = 0;
186 for(cid=bag_first(&children), i=1; cid; cid=bag_next(&children, cid), i++){
187
+1
--- src/tag.c
+++ src/tag.c
@@ -311,10 +311,11 @@
311311
blob_appendf(&ctrl, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
312312
md5sum_blob(&ctrl, &cksum);
313313
blob_appendf(&ctrl, "Z %b\n", &cksum);
314314
nrid = content_put(&ctrl, 0, 0, 0);
315315
manifest_crosslink(nrid, &ctrl);
316
+ assert( blob_is_reset(&ctrl) );
316317
}
317318
318319
/*
319320
** COMMAND: tag
320321
** Usage: %fossil tag SUBCOMMAND ...
321322
--- src/tag.c
+++ src/tag.c
@@ -311,10 +311,11 @@
311 blob_appendf(&ctrl, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
312 md5sum_blob(&ctrl, &cksum);
313 blob_appendf(&ctrl, "Z %b\n", &cksum);
314 nrid = content_put(&ctrl, 0, 0, 0);
315 manifest_crosslink(nrid, &ctrl);
 
316 }
317
318 /*
319 ** COMMAND: tag
320 ** Usage: %fossil tag SUBCOMMAND ...
321
--- src/tag.c
+++ src/tag.c
@@ -311,10 +311,11 @@
311 blob_appendf(&ctrl, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
312 md5sum_blob(&ctrl, &cksum);
313 blob_appendf(&ctrl, "Z %b\n", &cksum);
314 nrid = content_put(&ctrl, 0, 0, 0);
315 manifest_crosslink(nrid, &ctrl);
316 assert( blob_is_reset(&ctrl) );
317 }
318
319 /*
320 ** COMMAND: tag
321 ** Usage: %fossil tag SUBCOMMAND ...
322
+2
--- src/tkt.c
+++ src/tkt.c
@@ -485,10 +485,11 @@
485485
if( rid==0 ){
486486
fossil_panic("trouble committing ticket: %s", g.zErrMsg);
487487
}
488488
manifest_crosslink_begin();
489489
manifest_crosslink(rid, &tktchng);
490
+ assert( blob_is_reset(&tktchng) );
490491
manifest_crosslink_end();
491492
}
492493
return TH_RETURN;
493494
}
494495
@@ -1062,11 +1063,12 @@
10621063
fossil_panic("trouble committing ticket: %s", g.zErrMsg);
10631064
}
10641065
manifest_crosslink_begin();
10651066
manifest_crosslink(rid, &tktchng);
10661067
manifest_crosslink_end();
1068
+ assert( blob_is_reset(&tktchng) );
10671069
printf("ticket %s succeeded for UID %s\n",
10681070
(eCmd==set?"set":"add"),zTktUuid);
10691071
}
10701072
}
10711073
}
10721074
}
10731075
--- src/tkt.c
+++ src/tkt.c
@@ -485,10 +485,11 @@
485 if( rid==0 ){
486 fossil_panic("trouble committing ticket: %s", g.zErrMsg);
487 }
488 manifest_crosslink_begin();
489 manifest_crosslink(rid, &tktchng);
 
490 manifest_crosslink_end();
491 }
492 return TH_RETURN;
493 }
494
@@ -1062,11 +1063,12 @@
1062 fossil_panic("trouble committing ticket: %s", g.zErrMsg);
1063 }
1064 manifest_crosslink_begin();
1065 manifest_crosslink(rid, &tktchng);
1066 manifest_crosslink_end();
 
1067 printf("ticket %s succeeded for UID %s\n",
1068 (eCmd==set?"set":"add"),zTktUuid);
1069 }
1070 }
1071 }
1072 }
1073
--- src/tkt.c
+++ src/tkt.c
@@ -485,10 +485,11 @@
485 if( rid==0 ){
486 fossil_panic("trouble committing ticket: %s", g.zErrMsg);
487 }
488 manifest_crosslink_begin();
489 manifest_crosslink(rid, &tktchng);
490 assert( blob_is_reset(&tktchng) );
491 manifest_crosslink_end();
492 }
493 return TH_RETURN;
494 }
495
@@ -1062,11 +1063,12 @@
1063 fossil_panic("trouble committing ticket: %s", g.zErrMsg);
1064 }
1065 manifest_crosslink_begin();
1066 manifest_crosslink(rid, &tktchng);
1067 manifest_crosslink_end();
1068 assert( blob_is_reset(&tktchng) );
1069 printf("ticket %s succeeded for UID %s\n",
1070 (eCmd==set?"set":"add"),zTktUuid);
1071 }
1072 }
1073 }
1074 }
1075
+3 -3
--- src/wiki.c
+++ src/wiki.c
@@ -324,11 +324,11 @@
324324
blob_appendf(&wiki, "Z %b\n", &cksum);
325325
blob_reset(&cksum);
326326
nrid = content_put(&wiki, 0, 0, 0);
327327
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
328328
manifest_crosslink(nrid, &wiki);
329
- blob_reset(&wiki);
329
+ assert( blob_is_reset(&wiki) );
330330
content_deltify(rid, nrid, 0);
331331
}
332332
db_end_transaction(0);
333333
cgi_redirectf("wiki?name=%T", zPageName);
334334
}
@@ -496,11 +496,11 @@
496496
blob_appendf(&wiki, "Z %b\n", &cksum);
497497
blob_reset(&cksum);
498498
nrid = content_put(&wiki, 0, 0, 0);
499499
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
500500
manifest_crosslink(nrid, &wiki);
501
- blob_reset(&wiki);
501
+ assert( blob_is_reset(&wiki) );
502502
content_deltify(rid, nrid, 0);
503503
db_end_transaction(0);
504504
}
505505
cgi_redirectf("wiki?name=%T", zPageName);
506506
}
@@ -820,11 +820,11 @@
820820
blob_reset(&cksum);
821821
db_begin_transaction();
822822
nrid = content_put( &wiki, 0, 0, 0);
823823
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
824824
manifest_crosslink(nrid,&wiki);
825
- blob_reset(&wiki);
825
+ assert( blob_is_reset(&wiki) );
826826
content_deltify(rid,nrid,0);
827827
db_end_transaction(0);
828828
autosync(AUTOSYNC_PUSH);
829829
return 1;
830830
}
831831
--- src/wiki.c
+++ src/wiki.c
@@ -324,11 +324,11 @@
324 blob_appendf(&wiki, "Z %b\n", &cksum);
325 blob_reset(&cksum);
326 nrid = content_put(&wiki, 0, 0, 0);
327 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
328 manifest_crosslink(nrid, &wiki);
329 blob_reset(&wiki);
330 content_deltify(rid, nrid, 0);
331 }
332 db_end_transaction(0);
333 cgi_redirectf("wiki?name=%T", zPageName);
334 }
@@ -496,11 +496,11 @@
496 blob_appendf(&wiki, "Z %b\n", &cksum);
497 blob_reset(&cksum);
498 nrid = content_put(&wiki, 0, 0, 0);
499 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
500 manifest_crosslink(nrid, &wiki);
501 blob_reset(&wiki);
502 content_deltify(rid, nrid, 0);
503 db_end_transaction(0);
504 }
505 cgi_redirectf("wiki?name=%T", zPageName);
506 }
@@ -820,11 +820,11 @@
820 blob_reset(&cksum);
821 db_begin_transaction();
822 nrid = content_put( &wiki, 0, 0, 0);
823 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
824 manifest_crosslink(nrid,&wiki);
825 blob_reset(&wiki);
826 content_deltify(rid,nrid,0);
827 db_end_transaction(0);
828 autosync(AUTOSYNC_PUSH);
829 return 1;
830 }
831
--- src/wiki.c
+++ src/wiki.c
@@ -324,11 +324,11 @@
324 blob_appendf(&wiki, "Z %b\n", &cksum);
325 blob_reset(&cksum);
326 nrid = content_put(&wiki, 0, 0, 0);
327 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
328 manifest_crosslink(nrid, &wiki);
329 assert( blob_is_reset(&wiki) );
330 content_deltify(rid, nrid, 0);
331 }
332 db_end_transaction(0);
333 cgi_redirectf("wiki?name=%T", zPageName);
334 }
@@ -496,11 +496,11 @@
496 blob_appendf(&wiki, "Z %b\n", &cksum);
497 blob_reset(&cksum);
498 nrid = content_put(&wiki, 0, 0, 0);
499 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
500 manifest_crosslink(nrid, &wiki);
501 assert( blob_is_reset(&wiki) );
502 content_deltify(rid, nrid, 0);
503 db_end_transaction(0);
504 }
505 cgi_redirectf("wiki?name=%T", zPageName);
506 }
@@ -820,11 +820,11 @@
820 blob_reset(&cksum);
821 db_begin_transaction();
822 nrid = content_put( &wiki, 0, 0, 0);
823 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
824 manifest_crosslink(nrid,&wiki);
825 assert( blob_is_reset(&wiki) );
826 content_deltify(rid,nrid,0);
827 db_end_transaction(0);
828 autosync(AUTOSYNC_PUSH);
829 return 1;
830 }
831
+2
--- src/xfer.c
+++ src/xfer.c
@@ -163,14 +163,16 @@
163163
}
164164
rid = content_put(&content, blob_str(&hash), 0, 0);
165165
blob_reset(&hash);
166166
if( rid==0 ){
167167
blob_appendf(&pXfer->err, "%s", g.zErrMsg);
168
+ blob_reset(&content);
168169
}else{
169170
content_make_public(rid);
170171
manifest_crosslink(rid, &content);
171172
}
173
+ assert( blob_is_reset(&content) );
172174
remote_has(rid);
173175
}
174176
175177
/*
176178
** The aToken[0..nToken-1] blob array is a parse of a "cfile" line
177179
--- src/xfer.c
+++ src/xfer.c
@@ -163,14 +163,16 @@
163 }
164 rid = content_put(&content, blob_str(&hash), 0, 0);
165 blob_reset(&hash);
166 if( rid==0 ){
167 blob_appendf(&pXfer->err, "%s", g.zErrMsg);
 
168 }else{
169 content_make_public(rid);
170 manifest_crosslink(rid, &content);
171 }
 
172 remote_has(rid);
173 }
174
175 /*
176 ** The aToken[0..nToken-1] blob array is a parse of a "cfile" line
177
--- src/xfer.c
+++ src/xfer.c
@@ -163,14 +163,16 @@
163 }
164 rid = content_put(&content, blob_str(&hash), 0, 0);
165 blob_reset(&hash);
166 if( rid==0 ){
167 blob_appendf(&pXfer->err, "%s", g.zErrMsg);
168 blob_reset(&content);
169 }else{
170 content_make_public(rid);
171 manifest_crosslink(rid, &content);
172 }
173 assert( blob_is_reset(&content) );
174 remote_has(rid);
175 }
176
177 /*
178 ** The aToken[0..nToken-1] blob array is a parse of a "cfile" line
179

Keyboard Shortcuts

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