Fossil SCM

Make sure the "branch new --private" command does not create a public BLOB that is a delta of a private BLOB. Also, when doing a file clone or when doing "scrub --private", double-check that no public BLOBs are deltas of private BLOBs before deleting the private BLOBs.

drh 2012-02-04 00:30 trunk
Commit 034e887c356c38e73f7b0ff2b047d25abe944227
3 files changed +1 -1 +48 -5 +1 -5
+1 -1
--- src/branch.c
+++ src/branch.c
@@ -146,11 +146,11 @@
146146
db_end_transaction(1);
147147
fossil_exit(1);
148148
}
149149
}
150150
151
- brid = content_put(&branch);
151
+ brid = content_put_ex(&branch, 0, 0, 0, isPrivate);
152152
if( brid==0 ){
153153
fossil_panic("trouble committing manifest: %s", g.zErrMsg);
154154
}
155155
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
156156
if( manifest_crosslink(brid, &branch)==0 ){
157157
--- src/branch.c
+++ src/branch.c
@@ -146,11 +146,11 @@
146 db_end_transaction(1);
147 fossil_exit(1);
148 }
149 }
150
151 brid = content_put(&branch);
152 if( brid==0 ){
153 fossil_panic("trouble committing manifest: %s", g.zErrMsg);
154 }
155 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
156 if( manifest_crosslink(brid, &branch)==0 ){
157
--- src/branch.c
+++ src/branch.c
@@ -146,11 +146,11 @@
146 db_end_transaction(1);
147 fossil_exit(1);
148 }
149 }
150
151 brid = content_put_ex(&branch, 0, 0, 0, isPrivate);
152 if( brid==0 ){
153 fossil_panic("trouble committing manifest: %s", g.zErrMsg);
154 }
155 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid);
156 if( manifest_crosslink(brid, &branch)==0 ){
157
+48 -5
--- src/clone.c
+++ src/clone.c
@@ -19,10 +19,57 @@
1919
*/
2020
#include "config.h"
2121
#include "clone.h"
2222
#include <assert.h>
2323
24
+/*
25
+** Delete all private content from a repository.
26
+*/
27
+void delete_private_content(void){
28
+ Bag toUndelta;
29
+ Stmt q;
30
+ int rid;
31
+
32
+ /* Carefule: We are about to delete all BLOB entries that are private.
33
+ ** So make sure that any no public BLOBs are deltas from a private BLOB.
34
+ ** Otherwise after the deletion, we won't be able to recreate the public
35
+ ** BLOBs.
36
+ */
37
+ db_prepare(&q,
38
+ "SELECT "
39
+ " rid, (SELECT uuid FROM blob WHERE rid=delta.rid),"
40
+ " srcid, (SELECT uuid FROM blob WHERE rid=delta.srcid)"
41
+ " FROM delta"
42
+ " WHERE srcid in private AND rid NOT IN private"
43
+ );
44
+ bag_init(&toUndelta);
45
+ while( db_step(&q)==SQLITE_ROW ){
46
+ int rid = db_column_int(&q, 0);
47
+ const char *zId = db_column_text(&q, 1);
48
+ int srcid = db_column_int(&q, 2);
49
+ const char *zSrc = db_column_text(&q, 3);
50
+ fossil_warning(
51
+ "public artifact %S (%d) is a delta from private artifact %S (%d)\n",
52
+ zId, rid, zSrc, srcid
53
+ );
54
+ bag_insert(&toUndelta, rid);
55
+ }
56
+ db_finalize(&q);
57
+ while( (rid = bag_first(&toUndelta))>0 ){
58
+ content_undelta(rid);
59
+ bag_remove(&toUndelta, rid);
60
+ }
61
+ bag_clear(&toUndelta);
62
+
63
+ /* Now it is safe to remove all private content
64
+ */
65
+ db_multi_exec(
66
+ "DELETE FROM blob WHERE rid IN private;"
67
+ "DELETE FROM delta wHERE rid IN private;"
68
+ "DELETE FROM private;"
69
+ );
70
+}
2471
2572
2673
/*
2774
** COMMAND: clone
2875
**
@@ -72,15 +119,11 @@
72119
" VALUES('server-code', lower(hex(randomblob(20))),now());"
73120
"REPLACE INTO config(name,value,mtime)"
74121
" VALUES('last-sync-url', '%q',now());",
75122
g.urlCanonical
76123
);
77
- db_multi_exec(
78
- "DELETE FROM blob WHERE rid IN private;"
79
- "DELETE FROM delta wHERE rid IN private;"
80
- "DELETE FROM private;"
81
- );
124
+ delete_private_content();
82125
shun_artifacts();
83126
db_create_default_users(1, zDefaultUser);
84127
if( zDefaultUser ){
85128
g.zLogin = zDefaultUser;
86129
}else{
87130
--- src/clone.c
+++ src/clone.c
@@ -19,10 +19,57 @@
19 */
20 #include "config.h"
21 #include "clone.h"
22 #include <assert.h>
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
25
26 /*
27 ** COMMAND: clone
28 **
@@ -72,15 +119,11 @@
72 " VALUES('server-code', lower(hex(randomblob(20))),now());"
73 "REPLACE INTO config(name,value,mtime)"
74 " VALUES('last-sync-url', '%q',now());",
75 g.urlCanonical
76 );
77 db_multi_exec(
78 "DELETE FROM blob WHERE rid IN private;"
79 "DELETE FROM delta wHERE rid IN private;"
80 "DELETE FROM private;"
81 );
82 shun_artifacts();
83 db_create_default_users(1, zDefaultUser);
84 if( zDefaultUser ){
85 g.zLogin = zDefaultUser;
86 }else{
87
--- src/clone.c
+++ src/clone.c
@@ -19,10 +19,57 @@
19 */
20 #include "config.h"
21 #include "clone.h"
22 #include <assert.h>
23
24 /*
25 ** Delete all private content from a repository.
26 */
27 void delete_private_content(void){
28 Bag toUndelta;
29 Stmt q;
30 int rid;
31
32 /* Carefule: We are about to delete all BLOB entries that are private.
33 ** So make sure that any no public BLOBs are deltas from a private BLOB.
34 ** Otherwise after the deletion, we won't be able to recreate the public
35 ** BLOBs.
36 */
37 db_prepare(&q,
38 "SELECT "
39 " rid, (SELECT uuid FROM blob WHERE rid=delta.rid),"
40 " srcid, (SELECT uuid FROM blob WHERE rid=delta.srcid)"
41 " FROM delta"
42 " WHERE srcid in private AND rid NOT IN private"
43 );
44 bag_init(&toUndelta);
45 while( db_step(&q)==SQLITE_ROW ){
46 int rid = db_column_int(&q, 0);
47 const char *zId = db_column_text(&q, 1);
48 int srcid = db_column_int(&q, 2);
49 const char *zSrc = db_column_text(&q, 3);
50 fossil_warning(
51 "public artifact %S (%d) is a delta from private artifact %S (%d)\n",
52 zId, rid, zSrc, srcid
53 );
54 bag_insert(&toUndelta, rid);
55 }
56 db_finalize(&q);
57 while( (rid = bag_first(&toUndelta))>0 ){
58 content_undelta(rid);
59 bag_remove(&toUndelta, rid);
60 }
61 bag_clear(&toUndelta);
62
63 /* Now it is safe to remove all private content
64 */
65 db_multi_exec(
66 "DELETE FROM blob WHERE rid IN private;"
67 "DELETE FROM delta wHERE rid IN private;"
68 "DELETE FROM private;"
69 );
70 }
71
72
73 /*
74 ** COMMAND: clone
75 **
@@ -72,15 +119,11 @@
119 " VALUES('server-code', lower(hex(randomblob(20))),now());"
120 "REPLACE INTO config(name,value,mtime)"
121 " VALUES('last-sync-url', '%q',now());",
122 g.urlCanonical
123 );
124 delete_private_content();
 
 
 
 
125 shun_artifacts();
126 db_create_default_users(1, zDefaultUser);
127 if( zDefaultUser ){
128 g.zLogin = zDefaultUser;
129 }else{
130
+1 -5
--- src/rebuild.c
+++ src/rebuild.c
@@ -771,15 +771,11 @@
771771
}
772772
}
773773
db_begin_transaction();
774774
if( privateOnly || bVerily ){
775775
bNeedRebuild = db_exists("SELECT 1 FROM private");
776
- db_multi_exec(
777
- "DELETE FROM blob WHERE rid IN private;"
778
- "DELETE FROM delta WHERE rid IN private;"
779
- "DELETE FROM private;"
780
- );
776
+ delete_private_content();
781777
}
782778
if( !privateOnly ){
783779
db_multi_exec(
784780
"UPDATE user SET pw='';"
785781
"DELETE FROM config WHERE name GLOB 'last-sync-*';"
786782
--- src/rebuild.c
+++ src/rebuild.c
@@ -771,15 +771,11 @@
771 }
772 }
773 db_begin_transaction();
774 if( privateOnly || bVerily ){
775 bNeedRebuild = db_exists("SELECT 1 FROM private");
776 db_multi_exec(
777 "DELETE FROM blob WHERE rid IN private;"
778 "DELETE FROM delta WHERE rid IN private;"
779 "DELETE FROM private;"
780 );
781 }
782 if( !privateOnly ){
783 db_multi_exec(
784 "UPDATE user SET pw='';"
785 "DELETE FROM config WHERE name GLOB 'last-sync-*';"
786
--- src/rebuild.c
+++ src/rebuild.c
@@ -771,15 +771,11 @@
771 }
772 }
773 db_begin_transaction();
774 if( privateOnly || bVerily ){
775 bNeedRebuild = db_exists("SELECT 1 FROM private");
776 delete_private_content();
 
 
 
 
777 }
778 if( !privateOnly ){
779 db_multi_exec(
780 "UPDATE user SET pw='';"
781 "DELETE FROM config WHERE name GLOB 'last-sync-*';"
782

Keyboard Shortcuts

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