Fossil SCM

Do extra error checking to determine that a sync target given as a filename is a valid Fossil repository. Issue a better error message if it is not.

drh 2021-11-11 23:38 trunk
Commit 31361e328f89cbd7da6584f7cf131018078d6ae3cd86f9a8ce73521e00eb3b28
2 files changed +52 -1 +3
+52 -1
--- src/db.c
+++ src/db.c
@@ -2125,26 +2125,77 @@
21252125
** Returns non-zero if support for symlinks is currently enabled.
21262126
*/
21272127
int db_allow_symlinks(void){
21282128
return g.allowSymlinks;
21292129
}
2130
+
2131
+/*
2132
+** Return TRUE if the file in the argument seems like it might be an
2133
+** SQLite database file that contains a Fossil repository schema.
2134
+*/
2135
+int db_looks_like_a_repository(const char *zDbName){
2136
+ sqlite3 *db = 0;
2137
+ i64 sz;
2138
+ int rc;
2139
+ int res = 0;
2140
+ sqlite3_stmt *pStmt = 0;
2141
+
2142
+ sz = file_size(zDbName, ExtFILE);
2143
+ if( sz<16834 ) return 0;
2144
+ if( sz & 0x1ff ) return 0;
2145
+ rc = sqlite3_open(zDbName, &db);
2146
+ if( rc ) goto is_repo_end;
2147
+ rc = sqlite3_prepare_v2(db,
2148
+ "SELECT count(*) FROM sqlite_schema"
2149
+ " WHERE name COLLATE nocase IN"
2150
+ "('blob','delta','rcvfrom','user','config','mlink','plink');",
2151
+ -1, &pStmt, 0);
2152
+ if( rc ) goto is_repo_end;
2153
+ rc = sqlite3_step(pStmt);
2154
+ if( rc!=SQLITE_ROW ) goto is_repo_end;
2155
+ if( sqlite3_column_int(pStmt, 0)!=7 ) goto is_repo_end;
2156
+ res = 1;
2157
+
2158
+is_repo_end:
2159
+ sqlite3_finalize(pStmt);
2160
+ sqlite3_close(db);
2161
+ return res;
2162
+}
2163
+
2164
+/*
2165
+** COMMAND: test-is-repo
2166
+*/
2167
+void test_is_repo(void){
2168
+ int i;
2169
+ for(i=2; i<g.argc; i++){
2170
+ fossil_print("%s: %s\n",
2171
+ db_looks_like_a_repository(g.argv[i]) ? "yes" : " no",
2172
+ g.argv[i]
2173
+ );
2174
+ }
2175
+}
2176
+
21302177
21312178
/*
21322179
** Open the repository database given by zDbName. If zDbName==NULL then
21332180
** get the name from the already open local database.
21342181
*/
21352182
void db_open_repository(const char *zDbName){
2183
+ i64 sz;
21362184
if( g.repositoryOpen ) return;
21372185
if( zDbName==0 ){
21382186
if( g.localOpen ){
21392187
zDbName = db_repository_filename();
21402188
}
21412189
if( zDbName==0 ){
21422190
db_err("unable to find the name of a repository database");
21432191
}
21442192
}
2145
- if( file_access(zDbName, R_OK) || file_size(zDbName, ExtFILE)<1024 ){
2193
+ if( file_access(zDbName, R_OK)
2194
+ || (sz = file_size(zDbName, ExtFILE))<16384
2195
+ || (sz&0x1ff)!=0
2196
+ ){
21462197
if( file_access(zDbName, F_OK) ){
21472198
#ifdef FOSSIL_ENABLE_JSON
21482199
g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
21492200
#endif
21502201
fossil_fatal("repository does not exist or"
21512202
--- src/db.c
+++ src/db.c
@@ -2125,26 +2125,77 @@
2125 ** Returns non-zero if support for symlinks is currently enabled.
2126 */
2127 int db_allow_symlinks(void){
2128 return g.allowSymlinks;
2129 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2130
2131 /*
2132 ** Open the repository database given by zDbName. If zDbName==NULL then
2133 ** get the name from the already open local database.
2134 */
2135 void db_open_repository(const char *zDbName){
 
2136 if( g.repositoryOpen ) return;
2137 if( zDbName==0 ){
2138 if( g.localOpen ){
2139 zDbName = db_repository_filename();
2140 }
2141 if( zDbName==0 ){
2142 db_err("unable to find the name of a repository database");
2143 }
2144 }
2145 if( file_access(zDbName, R_OK) || file_size(zDbName, ExtFILE)<1024 ){
 
 
 
2146 if( file_access(zDbName, F_OK) ){
2147 #ifdef FOSSIL_ENABLE_JSON
2148 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2149 #endif
2150 fossil_fatal("repository does not exist or"
2151
--- src/db.c
+++ src/db.c
@@ -2125,26 +2125,77 @@
2125 ** Returns non-zero if support for symlinks is currently enabled.
2126 */
2127 int db_allow_symlinks(void){
2128 return g.allowSymlinks;
2129 }
2130
2131 /*
2132 ** Return TRUE if the file in the argument seems like it might be an
2133 ** SQLite database file that contains a Fossil repository schema.
2134 */
2135 int db_looks_like_a_repository(const char *zDbName){
2136 sqlite3 *db = 0;
2137 i64 sz;
2138 int rc;
2139 int res = 0;
2140 sqlite3_stmt *pStmt = 0;
2141
2142 sz = file_size(zDbName, ExtFILE);
2143 if( sz<16834 ) return 0;
2144 if( sz & 0x1ff ) return 0;
2145 rc = sqlite3_open(zDbName, &db);
2146 if( rc ) goto is_repo_end;
2147 rc = sqlite3_prepare_v2(db,
2148 "SELECT count(*) FROM sqlite_schema"
2149 " WHERE name COLLATE nocase IN"
2150 "('blob','delta','rcvfrom','user','config','mlink','plink');",
2151 -1, &pStmt, 0);
2152 if( rc ) goto is_repo_end;
2153 rc = sqlite3_step(pStmt);
2154 if( rc!=SQLITE_ROW ) goto is_repo_end;
2155 if( sqlite3_column_int(pStmt, 0)!=7 ) goto is_repo_end;
2156 res = 1;
2157
2158 is_repo_end:
2159 sqlite3_finalize(pStmt);
2160 sqlite3_close(db);
2161 return res;
2162 }
2163
2164 /*
2165 ** COMMAND: test-is-repo
2166 */
2167 void test_is_repo(void){
2168 int i;
2169 for(i=2; i<g.argc; i++){
2170 fossil_print("%s: %s\n",
2171 db_looks_like_a_repository(g.argv[i]) ? "yes" : " no",
2172 g.argv[i]
2173 );
2174 }
2175 }
2176
2177
2178 /*
2179 ** Open the repository database given by zDbName. If zDbName==NULL then
2180 ** get the name from the already open local database.
2181 */
2182 void db_open_repository(const char *zDbName){
2183 i64 sz;
2184 if( g.repositoryOpen ) return;
2185 if( zDbName==0 ){
2186 if( g.localOpen ){
2187 zDbName = db_repository_filename();
2188 }
2189 if( zDbName==0 ){
2190 db_err("unable to find the name of a repository database");
2191 }
2192 }
2193 if( file_access(zDbName, R_OK)
2194 || (sz = file_size(zDbName, ExtFILE))<16384
2195 || (sz&0x1ff)!=0
2196 ){
2197 if( file_access(zDbName, F_OK) ){
2198 #ifdef FOSSIL_ENABLE_JSON
2199 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2200 #endif
2201 fossil_fatal("repository does not exist or"
2202
--- src/http_transport.c
+++ src/http_transport.c
@@ -178,10 +178,13 @@
178178
socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
179179
rc = 1;
180180
#endif
181181
}else if( pUrlData->isFile ){
182182
sqlite3_uint64 iRandId;
183
+ if( !db_looks_like_a_repository(pUrlData->name) ){
184
+ fossil_fatal("not a fossil repository: \"%s\"", pUrlData->name);
185
+ }
183186
sqlite3_randomness(sizeof(iRandId), &iRandId);
184187
transport.zOutFile = mprintf("%s-%llu-out.http",
185188
g.zRepositoryName, iRandId);
186189
transport.zInFile = mprintf("%s-%llu-in.http",
187190
g.zRepositoryName, iRandId);
188191
--- src/http_transport.c
+++ src/http_transport.c
@@ -178,10 +178,13 @@
178 socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
179 rc = 1;
180 #endif
181 }else if( pUrlData->isFile ){
182 sqlite3_uint64 iRandId;
 
 
 
183 sqlite3_randomness(sizeof(iRandId), &iRandId);
184 transport.zOutFile = mprintf("%s-%llu-out.http",
185 g.zRepositoryName, iRandId);
186 transport.zInFile = mprintf("%s-%llu-in.http",
187 g.zRepositoryName, iRandId);
188
--- src/http_transport.c
+++ src/http_transport.c
@@ -178,10 +178,13 @@
178 socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
179 rc = 1;
180 #endif
181 }else if( pUrlData->isFile ){
182 sqlite3_uint64 iRandId;
183 if( !db_looks_like_a_repository(pUrlData->name) ){
184 fossil_fatal("not a fossil repository: \"%s\"", pUrlData->name);
185 }
186 sqlite3_randomness(sizeof(iRandId), &iRandId);
187 transport.zOutFile = mprintf("%s-%llu-out.http",
188 g.zRepositoryName, iRandId);
189 transport.zInFile = mprintf("%s-%llu-in.http",
190 g.zRepositoryName, iRandId);
191

Keyboard Shortcuts

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