Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Version 2.10.2 |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | release | version-2.10.2 | branch-2.10 |
| Files: | files | file ages | folders |
| SHA3-256: |
12d2ad00deb19c241515852cdab1f19e |
| User & Date: | drh 2020-08-20 13:18:36.439 |
Context
|
2020-08-20
| ||
| 13:18 | Version 2.10.2 ... (Leaf check-in: 12d2ad00de user: drh tags: release, version-2.10.2, branch-2.10) | |
| 13:01 | 2.12.1 release candidate with security fixes. ... (check-in: 40feec3291 user: drh tags: branch-2.12) | |
|
2020-06-08
| ||
| 20:08 | Version 2.10.1 ... (check-in: 674782c7a1 user: drh tags: release, version-2.10.1, branch-2.10) | |
Changes
Changes to VERSION.
|
| | | 1 | 2.10.2 |
Changes to src/add.c.
| ︙ | ︙ | |||
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
**
** Omit any file whose name is pOmit.
*/
static int add_one_file(
const char *zPath, /* Tree-name of file to add. */
int vid /* Add to this VFILE */
){
if( !file_is_simple_pathname(zPath, 1) ){
fossil_warning("filename contains illegal characters: %s", zPath);
return 0;
}
if( db_exists("SELECT 1 FROM vfile"
" WHERE pathname=%Q %s", zPath, filename_collation()) ){
db_multi_exec("UPDATE vfile SET deleted=0"
" WHERE pathname=%Q %s AND deleted",
zPath, filename_collation());
}else{
char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath);
int isExe = file_isexe(zFullname, RepoFILE);
| > > > > > | | | | > | | > > | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
**
** Omit any file whose name is pOmit.
*/
static int add_one_file(
const char *zPath, /* Tree-name of file to add. */
int vid /* Add to this VFILE */
){
int doSkip = 0;
if( !file_is_simple_pathname(zPath, 1) ){
fossil_warning("filename contains illegal characters: %s", zPath);
return 0;
}
if( db_exists("SELECT 1 FROM vfile"
" WHERE pathname=%Q %s", zPath, filename_collation()) ){
db_multi_exec("UPDATE vfile SET deleted=0"
" WHERE pathname=%Q %s AND deleted",
zPath, filename_collation());
}else{
char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath);
int isExe = file_isexe(zFullname, RepoFILE);
if( file_nondir_objects_on_path(g.zLocalRoot, zFullname) ){
/* Do not add unsafe files to the vfile */
doSkip = 1;
}else{
db_multi_exec(
"INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe,islink,mhash)"
"VALUES(%d,0,0,0,%Q,%d,%d,NULL)",
vid, zPath, isExe, file_islink(0));
}
fossil_free(zFullname);
}
if( db_changes() && !doSkip ){
fossil_print("ADDED %s\n", zPath);
return 1;
}else{
fossil_print("SKIP %s\n", zPath);
return 0;
}
}
/*
** Add all files in the sfile temp table.
**
** Automatically exclude the repository file and any other files
** with reserved names. Also exclude files that are beneath an
** existing symlink.
*/
static int add_files_in_sfile(int vid){
const char *zRepo; /* Name of the repository database file */
int nAdd = 0; /* Number of files added */
int i; /* Loop counter */
const char *zReserved; /* Name of a reserved file */
Blob repoName; /* Treename of the repository */
|
| ︙ | ︙ | |||
224 225 226 227 228 229 230 |
zRepo = blob_str(&repoName);
}
if( filenames_are_case_sensitive() ){
xCmp = fossil_strcmp;
}else{
xCmp = fossil_stricmp;
}
| | > > > > > > > > > > > | | | | > | 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
zRepo = blob_str(&repoName);
}
if( filenames_are_case_sensitive() ){
xCmp = fossil_strcmp;
}else{
xCmp = fossil_stricmp;
}
db_prepare(&loop,
"SELECT pathname FROM sfile"
" WHERE pathname NOT IN ("
"SELECT sfile.pathname FROM vfile, sfile"
" WHERE vfile.islink"
" AND NOT vfile.deleted"
" AND sfile.pathname>(vfile.pathname||'/')"
" AND sfile.pathname<(vfile.pathname||'0'))"
" ORDER BY pathname");
while( db_step(&loop)==SQLITE_ROW ){
const char *zToAdd = db_column_text(&loop, 0);
if( fossil_strcmp(zToAdd, zRepo)==0 ) continue;
if( strchr(zToAdd,'/') ){
if( file_is_reserved_name(zToAdd, -1) ) continue;
}else{
for(i=0; (zReserved = fossil_reserved_name(i, 0))!=0; i++){
if( xCmp(zToAdd, zReserved)==0 ) break;
}
if( zReserved ) continue;
}
nAdd += add_one_file(zToAdd, vid);
}
db_finalize(&loop);
blob_reset(&repoName);
return nAdd;
}
|
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 |
/* We should be done with options.. */
verify_all_options();
if( zIgnoreFlag==0 ){
zIgnoreFlag = db_get("ignore-glob", 0);
}
pIgnore = glob_create(zIgnoreFlag);
/* Always consider symlinks. */
g.allowSymlinks = db_allow_symlinks_by_default();
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
glob_free(pIgnore);
blob_zero(&report);
status_report(&report, flags);
if( blob_size(&report) ){
if( showHdr ){
| > > | 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 |
/* We should be done with options.. */
verify_all_options();
if( zIgnoreFlag==0 ){
zIgnoreFlag = db_get("ignore-glob", 0);
}
pIgnore = glob_create(zIgnoreFlag);
#ifdef FOSSIL_LEGACY_ALLOW_SYMLINKS
/* Always consider symlinks. */
g.allowSymlinks = db_allow_symlinks_by_default();
#endif
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
glob_free(pIgnore);
blob_zero(&report);
status_report(&report, flags);
if( blob_size(&report) ){
if( showHdr ){
|
| ︙ | ︙ | |||
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 |
}
if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
verify_all_options();
pIgnore = glob_create(zIgnoreFlag);
pKeep = glob_create(zKeepFlag);
pClean = glob_create(zCleanFlag);
nRoot = (int)strlen(g.zLocalRoot);
/* Always consider symlinks. */
g.allowSymlinks = db_allow_symlinks_by_default();
if( !dirsOnlyFlag ){
Stmt q;
Blob repo;
if( !dryRunFlag && !disableUndo ) undo_begin();
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
db_prepare(&q,
"SELECT %Q || pathname FROM sfile"
| > > | 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 |
}
if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
verify_all_options();
pIgnore = glob_create(zIgnoreFlag);
pKeep = glob_create(zKeepFlag);
pClean = glob_create(zCleanFlag);
nRoot = (int)strlen(g.zLocalRoot);
#ifdef FOSSIL_LEGACY_ALLOW_SYMLINKS
/* Always consider symlinks. */
g.allowSymlinks = db_allow_symlinks_by_default();
#endif
if( !dirsOnlyFlag ){
Stmt q;
Blob repo;
if( !dryRunFlag && !disableUndo ) undo_begin();
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
db_prepare(&q,
"SELECT %Q || pathname FROM sfile"
|
| ︙ | ︙ |
Changes to src/configure.c.
| ︙ | ︙ | |||
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
{ "clean-glob", CONFIGSET_PROJ },
{ "ignore-glob", CONFIGSET_PROJ },
{ "keep-glob", CONFIGSET_PROJ },
{ "crlf-glob", CONFIGSET_PROJ },
{ "crnl-glob", CONFIGSET_PROJ },
{ "encoding-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
{ "allow-symlinks", CONFIGSET_PROJ },
{ "dotfiles", CONFIGSET_PROJ },
{ "parent-project-code", CONFIGSET_PROJ },
{ "parent-project-name", CONFIGSET_PROJ },
{ "hash-policy", CONFIGSET_PROJ },
{ "comment-format", CONFIGSET_PROJ },
#ifdef FOSSIL_ENABLE_LEGACY_MV_RM
| > > | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
{ "clean-glob", CONFIGSET_PROJ },
{ "ignore-glob", CONFIGSET_PROJ },
{ "keep-glob", CONFIGSET_PROJ },
{ "crlf-glob", CONFIGSET_PROJ },
{ "crnl-glob", CONFIGSET_PROJ },
{ "encoding-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
#ifdef FOSSIL_LEGACY_ALLOW_SYMLINKS
{ "allow-symlinks", CONFIGSET_PROJ },
#endif
{ "dotfiles", CONFIGSET_PROJ },
{ "parent-project-code", CONFIGSET_PROJ },
{ "parent-project-name", CONFIGSET_PROJ },
{ "hash-policy", CONFIGSET_PROJ },
{ "comment-format", CONFIGSET_PROJ },
#ifdef FOSSIL_ENABLE_LEGACY_MV_RM
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
} aHook[5];
char *azDeleteOnFail[3]; /* Files to delete on a failure */
char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
int nBeforeCommit; /* Number of entries in azBeforeCommit */
int nPriorChanges; /* sqlite3_total_changes() at transaction start */
const char *zStartFile; /* File in which transaction was started */
int iStartLine; /* Line of zStartFile where transaction started */
} db = {0, 0, 0, 0, 0, 0, };
/*
** Arrange for the given file to be deleted on a failure.
*/
void db_delete_on_failure(const char *zFilename){
assert( db.nDeleteOnFail<count(db.azDeleteOnFail) );
| > > > | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
} aHook[5];
char *azDeleteOnFail[3]; /* Files to delete on a failure */
char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
int nBeforeCommit; /* Number of entries in azBeforeCommit */
int nPriorChanges; /* sqlite3_total_changes() at transaction start */
const char *zStartFile; /* File in which transaction was started */
int iStartLine; /* Line of zStartFile where transaction started */
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
void *pAuthArg; /* Argument to the authorizer */
const char *zAuthName; /* Name of the authorizer */
} db = {0, 0, 0, 0, 0, 0, };
/*
** Arrange for the given file to be deleted on a failure.
*/
void db_delete_on_failure(const char *zFilename){
assert( db.nDeleteOnFail<count(db.azDeleteOnFail) );
|
| ︙ | ︙ | |||
304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
db.aHook[i].xHook = xS;
}
}
db.aHook[db.nCommitHook].sequence = sequence;
db.aHook[db.nCommitHook].xHook = x;
db.nCommitHook++;
}
#if INTERFACE
/*
** Possible flags to db_vprepare
*/
#define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
#define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
| > > > > > > > > > > > > > > > > > > > > > > > > > > | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
db.aHook[i].xHook = xS;
}
}
db.aHook[db.nCommitHook].sequence = sequence;
db.aHook[db.nCommitHook].xHook = x;
db.nCommitHook++;
}
/*
** Set or unset the query authorizer callback function
*/
void db_set_authorizer(
int(*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg,
const char *zName /* for tracing */
){
if( db.xAuth ){
fossil_panic("multiple active db_set_authorizer() calls");
}
if( g.db ) sqlite3_set_authorizer(g.db, xAuth, pArg);
db.xAuth = xAuth;
db.pAuthArg = pArg;
db.zAuthName = zName;
if( g.fSqlTrace ) fossil_trace("-- set authorizer %s\n", zName);
}
void db_clear_authorizer(void){
if( db.zAuthName && g.fSqlTrace ){
fossil_trace("-- discontinue authorizer %s\n", db.zAuthName);
}
if( g.db ) sqlite3_set_authorizer(g.db, 0, 0);
db.xAuth = 0;
db.pAuthArg = 0;
}
#if INTERFACE
/*
** Possible flags to db_vprepare
*/
#define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
#define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
|
| ︙ | ︙ | |||
822 823 824 825 826 827 828 |
** database.
*/
void db_init_database(
const char *zFileName, /* Name of database file to create */
const char *zSchema, /* First part of schema */
... /* Additional SQL to run. Terminate with NULL. */
){
| | | | > > > | | | | | | | | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 |
** database.
*/
void db_init_database(
const char *zFileName, /* Name of database file to create */
const char *zSchema, /* First part of schema */
... /* Additional SQL to run. Terminate with NULL. */
){
sqlite3 *xdb;
int rc;
const char *zSql;
va_list ap;
xdb = db_open(zFileName ? zFileName : ":memory:");
sqlite3_exec(xdb, "BEGIN EXCLUSIVE", 0, 0, 0);
if( db.xAuth ){
sqlite3_set_authorizer(xdb, db.xAuth, db.pAuthArg);
}
rc = sqlite3_exec(xdb, zSchema, 0, 0, 0);
if( rc!=SQLITE_OK ){
db_err("%s", sqlite3_errmsg(xdb));
}
va_start(ap, zSchema);
while( (zSql = va_arg(ap, const char*))!=0 ){
rc = sqlite3_exec(xdb, zSql, 0, 0, 0);
if( rc!=SQLITE_OK ){
db_err("%s", sqlite3_errmsg(xdb));
}
}
va_end(ap);
sqlite3_exec(xdb, "COMMIT", 0, 0, 0);
if( zFileName || g.db!=0 ){
sqlite3_close(xdb);
}else{
g.db = xdb;
}
}
/*
** Function to return the number of seconds since 1970. This is
** the same as strftime('%s','now') but is more compact.
*/
|
| ︙ | ︙ | |||
1637 1638 1639 1640 1641 1642 1643 |
}
/*
** Returns non-zero if the default value for the "allow-symlinks" setting
** is "on". When on Windows, this always returns false.
*/
int db_allow_symlinks_by_default(void){
| | | 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 |
}
/*
** Returns non-zero if the default value for the "allow-symlinks" setting
** is "on". When on Windows, this always returns false.
*/
int db_allow_symlinks_by_default(void){
#if defined(_WIN32) || !defined(FOSSIL_LEGACY_ALLOW_SYMLINKS)
return 0;
#else
return 1;
#endif
}
/*
|
| ︙ | ︙ | |||
1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 |
**
** Check for unfinalized statements and report errors if the reportErrors
** argument is true. Ignore unfinalized statements when false.
*/
void db_close(int reportErrors){
sqlite3_stmt *pStmt;
if( g.db==0 ) return;
if( g.fSqlStats ){
int cur, hiwtr;
sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, &hiwtr, 0);
fprintf(stderr, "-- LOOKASIDE_USED %10d %10d\n", cur, hiwtr);
sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &cur, &hiwtr, 0);
fprintf(stderr, "-- LOOKASIDE_HIT %10d\n", hiwtr);
sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &cur,&hiwtr,0);
| > | 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 |
**
** Check for unfinalized statements and report errors if the reportErrors
** argument is true. Ignore unfinalized statements when false.
*/
void db_close(int reportErrors){
sqlite3_stmt *pStmt;
if( g.db==0 ) return;
sqlite3_set_authorizer(g.db, 0, 0);
if( g.fSqlStats ){
int cur, hiwtr;
sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, &hiwtr, 0);
fprintf(stderr, "-- LOOKASIDE_USED %10d %10d\n", cur, hiwtr);
sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &cur, &hiwtr, 0);
fprintf(stderr, "-- LOOKASIDE_HIT %10d\n", hiwtr);
sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &cur,&hiwtr,0);
|
| ︙ | ︙ | |||
1959 1960 1961 1962 1963 1964 1965 |
sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &cur, &hiwtr, 0);
fprintf(stderr, "-- PCACHE_OVFLOW %10d %10d\n", cur, hiwtr);
fprintf(stderr, "-- prepared statements %10d\n", db.nPrepare);
}
while( db.pAllStmt ){
db_finalize(db.pAllStmt);
}
| | > | | > > | | 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 |
sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &cur, &hiwtr, 0);
fprintf(stderr, "-- PCACHE_OVFLOW %10d %10d\n", cur, hiwtr);
fprintf(stderr, "-- prepared statements %10d\n", db.nPrepare);
}
while( db.pAllStmt ){
db_finalize(db.pAllStmt);
}
if( db.nBegin ){
if( reportErrors ){
fossil_warning("Transaction started at %s:%d never commits",
db.zStartFile, db.iStartLine);
}
db_end_transaction(1);
}
pStmt = 0;
sqlite3_busy_timeout(g.db, 0);
g.dbIgnoreErrors++; /* Stop "database locked" warnings */
sqlite3_exec(g.db, "PRAGMA optimize", 0, 0, 0);
g.dbIgnoreErrors--;
db_close_config();
/* If the localdb has a lot of unused free space,
** then VACUUM it as we shut down.
*/
|
| ︙ | ︙ | |||
2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 |
*/
void db_panic_close(void){
if( g.db ){
int rc;
sqlite3_wal_checkpoint(g.db, 0);
rc = sqlite3_close(g.db);
if( g.fSqlTrace ) fossil_trace("-- sqlite3_close(%d)\n", rc);
}
g.db = 0;
g.repositoryOpen = 0;
g.localOpen = 0;
}
/*
| > | 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 |
*/
void db_panic_close(void){
if( g.db ){
int rc;
sqlite3_wal_checkpoint(g.db, 0);
rc = sqlite3_close(g.db);
if( g.fSqlTrace ) fossil_trace("-- sqlite3_close(%d)\n", rc);
db_clear_authorizer();
}
g.db = 0;
g.repositoryOpen = 0;
g.localOpen = 0;
}
/*
|
| ︙ | ︙ | |||
2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 |
dflt = 1;
}else if( is_false(zVal) ){
dflt = 0;
}
fossil_free(zVal);
return dflt;
}
int db_get_versioned_boolean(const char *zName, int dflt){
char *zVal = db_get_versioned(zName, 0);
if( zVal==0 ) return dflt;
if( is_truth(zVal) ) return 1;
if( is_false(zVal) ) return 0;
return dflt;
}
char *db_lget(const char *zName, const char *zDefault){
return db_text(zDefault,
"SELECT value FROM vvar WHERE name=%Q", zName);
}
void db_lset(const char *zName, const char *zValue){
db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
}
| > > | 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 |
dflt = 1;
}else if( is_false(zVal) ){
dflt = 0;
}
fossil_free(zVal);
return dflt;
}
#ifdef FOSSIL_LEGACY_ALLOW_SYMLINKS
int db_get_versioned_boolean(const char *zName, int dflt){
char *zVal = db_get_versioned(zName, 0);
if( zVal==0 ) return dflt;
if( is_truth(zVal) ) return 1;
if( is_false(zVal) ) return 0;
return dflt;
}
#endif /* FOSSIL_LEGACY_ALLOW_SYMLINKS */
char *db_lget(const char *zName, const char *zDefault){
return db_text(zDefault,
"SELECT value FROM vvar WHERE name=%Q", zName);
}
void db_lset(const char *zName, const char *zValue){
db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
}
|
| ︙ | ︙ | |||
2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 |
** See also: close
*/
void cmd_open(void){
int emptyFlag;
int keepFlag;
int forceMissingFlag;
int allowNested;
int allowSymlinks;
int setmtimeFlag; /* --setmtime. Set mtimes on files */
static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
url_proxy_options();
emptyFlag = find_option("empty",0,0)!=0;
keepFlag = find_option("keep",0,0)!=0;
forceMissingFlag = find_option("force-missing",0,0)!=0;
| > > | 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 |
** See also: close
*/
void cmd_open(void){
int emptyFlag;
int keepFlag;
int forceMissingFlag;
int allowNested;
#ifdef FOSSIL_LEGACY_ALLOW_SYMLINKS
int allowSymlinks;
#endif
int setmtimeFlag; /* --setmtime. Set mtimes on files */
static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
url_proxy_options();
emptyFlag = find_option("empty",0,0)!=0;
keepFlag = find_option("keep",0,0)!=0;
forceMissingFlag = find_option("force-missing",0,0)!=0;
|
| ︙ | ︙ | |||
2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 |
if( g.argc==4 ){
g.zOpenRevision = g.argv[3];
}else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
g.zOpenRevision = db_get("main-branch", 0);
}
}
if( g.zOpenRevision ){
/* Since the repository is open and we know the revision now,
** refresh the allow-symlinks flag. Since neither the local
** checkout nor the configuration database are open at this
** point, this should always return the versioned setting,
** if any, or the default value, which is negative one. The
** value negative one, in this context, means that the code
** below should fallback to using the setting value from the
** repository or global configuration databases only. */
allowSymlinks = db_get_versioned_boolean("allow-symlinks", -1);
}else{
allowSymlinks = -1; /* Use non-versioned settings only. */
}
#if defined(_WIN32) || defined(__CYGWIN__)
# define LOCALDB_NAME "./_FOSSIL_"
#else
# define LOCALDB_NAME "./.fslckout"
#endif
db_init_database(LOCALDB_NAME, zLocalSchema, zLocalSchemaVmerge,
#ifdef FOSSIL_LOCAL_WAL
"COMMIT; PRAGMA journal_mode=WAL; BEGIN;",
#endif
(char*)0);
db_delete_on_failure(LOCALDB_NAME);
db_open_local(0);
if( allowSymlinks>=0 ){
/* Use the value from the versioned setting, which was read
** prior to opening the local checkout (i.e. which is most
** likely empty and does not actually contain any versioned
** setting files yet). Normally, this value would be given
** first priority within db_get_boolean(); however, this is
** a special case because we know the on-disk files may not
** exist yet. */
g.allowSymlinks = allowSymlinks;
}else{
/* Since the local checkout may not have any files at this
** point, this will probably be the setting value from the
** repository or global configuration databases. */
g.allowSymlinks = db_get_boolean("allow-symlinks",
db_allow_symlinks_by_default());
}
db_lset("repository", g.argv[2]);
db_record_repository_filename(g.argv[2]);
db_set_checkout(0);
azNewArgv[0] = g.argv[0];
g.argv = azNewArgv;
if( !emptyFlag ){
g.argc = 3;
| > > > > | 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 |
if( g.argc==4 ){
g.zOpenRevision = g.argv[3];
}else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
g.zOpenRevision = db_get("main-branch", 0);
}
}
#ifdef FOSSIL_LEGACY_ALLOW_SYMLINKS
if( g.zOpenRevision ){
/* Since the repository is open and we know the revision now,
** refresh the allow-symlinks flag. Since neither the local
** checkout nor the configuration database are open at this
** point, this should always return the versioned setting,
** if any, or the default value, which is negative one. The
** value negative one, in this context, means that the code
** below should fallback to using the setting value from the
** repository or global configuration databases only. */
allowSymlinks = db_get_versioned_boolean("allow-symlinks", -1);
}else{
allowSymlinks = -1; /* Use non-versioned settings only. */
}
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
# define LOCALDB_NAME "./_FOSSIL_"
#else
# define LOCALDB_NAME "./.fslckout"
#endif
db_init_database(LOCALDB_NAME, zLocalSchema, zLocalSchemaVmerge,
#ifdef FOSSIL_LOCAL_WAL
"COMMIT; PRAGMA journal_mode=WAL; BEGIN;",
#endif
(char*)0);
db_delete_on_failure(LOCALDB_NAME);
db_open_local(0);
#ifdef FOSSIL_LEGACY_ALLOW_SYMLINKS
if( allowSymlinks>=0 ){
/* Use the value from the versioned setting, which was read
** prior to opening the local checkout (i.e. which is most
** likely empty and does not actually contain any versioned
** setting files yet). Normally, this value would be given
** first priority within db_get_boolean(); however, this is
** a special case because we know the on-disk files may not
** exist yet. */
g.allowSymlinks = allowSymlinks;
}else{
/* Since the local checkout may not have any files at this
** point, this will probably be the setting value from the
** repository or global configuration databases. */
g.allowSymlinks = db_get_boolean("allow-symlinks",
db_allow_symlinks_by_default());
}
#endif /* FOSSIL_LEGACY_ALLOW_SYMLINKS */
db_lset("repository", g.argv[2]);
db_record_repository_filename(g.argv[2]);
db_set_checkout(0);
azNewArgv[0] = g.argv[0];
g.argv = azNewArgv;
if( !emptyFlag ){
g.argc = 3;
|
| ︙ | ︙ | |||
3105 3106 3107 3108 3109 3110 3111 | */ /* ** SETTING: admin-log boolean default=off ** ** When the admin-log setting is enabled, configuration changes are recorded ** in the "admin_log" table of the repository. */ | > > > > > > > > > > > > > > > > > > | | | 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 | */ /* ** SETTING: admin-log boolean default=off ** ** When the admin-log setting is enabled, configuration changes are recorded ** in the "admin_log" table of the repository. */ #if !defined(FOSSIL_LEGACY_ALLOW_SYMLINKS) /* ** SETTING: allow-symlinks boolean default=off ** ** When allow-symlinks is OFF (which is the default and recommended setting) ** symbolic links are treated like text files that contain a single line of ** content which is the name of their target. If allow-symlinks is ON, ** the symbolic links are actually followed. ** ** The use of symbolic links is dangerous. If you checkout a maliciously ** crafted checkin that contains symbolic links, it is possible that files ** outside of the working directory might be overwritten. ** ** Keep this setting OFF unless you have a very good reason to turn it ** on and you implicitly trust the integrity of the repositories you ** open. */ #endif #if defined(_WIN32) && defined(FOSSIL_LEGACY_ALLOW_SYMLINKS) /* ** SETTING: allow-symlinks boolean default=off versionable ** ** When allow-symlinks is OFF, symbolic links in the repository are followed ** and treated no differently from real files. When allow-symlinks is ON, ** the object to which the symbolic link points is ignored, and the content ** of the symbolic link that is stored in the repository is the name of the ** object to which the symbolic link points. */ #endif #if !defined(_WIN32) && defined(FOSSIL_LEGACY_ALLOW_SYMLINKS) /* ** SETTING: allow-symlinks boolean default=on versionable ** ** When allow-symlinks is OFF, symbolic links in the repository are followed ** and treated no differently from real files. When allow-symlinks is ON, ** the object to which the symbolic link points is ignored, and the content ** of the symbolic link that is stored in the repository is the name of the |
| ︙ | ︙ |
Changes to src/file.c.
| ︙ | ︙ | |||
321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
** This routines RepoFILE - that zFilename is always a file under management.
**
** On Windows, always return False.
*/
int file_islink(const char *zFilename){
return file_perm(zFilename, RepoFILE)==PERM_LNK;
}
/*
** Return 1 if zFilename is a directory. Return 0 if zFilename
** does not exist. Return 2 if zFilename exists but is something
** other than a directory.
*/
int file_isdir(const char *zFilename, int eFType){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
** This routines RepoFILE - that zFilename is always a file under management.
**
** On Windows, always return False.
*/
int file_islink(const char *zFilename){
return file_perm(zFilename, RepoFILE)==PERM_LNK;
}
/*
** Check every sub-directory of zRoot along the path to zFile.
** If any sub-directory is really an ordinary file or a symbolic link,
** return an integer which is the length of the prefix of zFile which
** is the name of that object. Return 0 if all no non-directory
** objects are found along the path.
**
** Example: Given inputs
**
** zRoot = /home/alice/project1
** zFile = /home/alice/project1/main/src/js/fileA.js
**
** Look for objects in the following order:
**
** /home/alice/project/main
** /home/alice/project/main/src
** /home/alice/project/main/src/js
**
** If any of those objects exist and are something other than a directory
** then return the length of the name of the first non-directory object
** seen.
*/
int file_nondir_objects_on_path(const char *zRoot, const char *zFile){
int i = (int)strlen(zRoot);
char *z = fossil_strdup(zFile);
assert( fossil_strnicmp(zRoot, z, i)==0 );
if( i && zRoot[i-1]=='/' ) i--;
while( z[i]=='/' ){
int j, rc;
for(j=i+1; z[j] && z[j]!='/'; j++){}
if( z[j]!='/' ) break;
z[j] = 0;
rc = file_isdir(z, SymFILE);
if( rc!=1 ){
if( rc==2 ){
fossil_free(z);
return j;
}
break;
}
z[j] = '/';
i = j;
}
fossil_free(z);
return 0;
}
/*
** The file named zFile is suppose to be an in-tree file. Check to
** ensure that it will be safe to write to this file by verifying that
** there are no symlinks or other non-directory objects in between the
** root of the checkout and zFile.
**
** If a problem is found, print a warning message (using fossil_warning())
** and return non-zero. If everything is ok, return zero.
*/
int file_unsafe_in_tree_path(const char *zFile){
int n;
if( !file_is_absolute_path(zFile) ){
fossil_panic("%s is not an absolute pathname",zFile);
}
if( fossil_strnicmp(g.zLocalRoot, zFile, (int)strlen(g.zLocalRoot)) ){
fossil_panic("%s is not a prefix of %s", g.zLocalRoot, zFile);
}
n = file_nondir_objects_on_path(g.zLocalRoot, zFile);
if( n ){
fossil_warning("cannot write to %s because non-directory object %.*s"
" is in the way", zFile, n, zFile);
}
return n;
}
/*
** Return 1 if zFilename is a directory. Return 0 if zFilename
** does not exist. Return 2 if zFilename exists but is something
** other than a directory.
*/
int file_isdir(const char *zFilename, int eFType){
|
| ︙ | ︙ | |||
527 528 529 530 531 532 533 |
** zFilename is a symbolic link, it is the object that zFilename points
** to that is modified.
*/
int file_setexe(const char *zFilename, int onoff){
int rc = 0;
#if !defined(_WIN32)
struct stat buf;
| | > > > | 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 |
** zFilename is a symbolic link, it is the object that zFilename points
** to that is modified.
*/
int file_setexe(const char *zFilename, int onoff){
int rc = 0;
#if !defined(_WIN32)
struct stat buf;
if( fossil_stat(zFilename, &buf, RepoFILE)!=0
|| S_ISLNK(buf.st_mode)
|| S_ISDIR(buf.st_mode)
){
return 0;
}
if( onoff ){
int targetMode = (buf.st_mode & 0444)>>2;
if( (buf.st_mode & 0100)==0 ){
chmod(zFilename, buf.st_mode | targetMode);
rc = 1;
|
| ︙ | ︙ | |||
2224 2225 2226 2227 2228 2229 2230 |
if( dryRunFlag!=0 ){
fossil_print("dry-run: would have touched %d file(s)\n",
changeCount);
}else{
fossil_print("Touched %d file(s)\n", changeCount);
}
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 |
if( dryRunFlag!=0 ){
fossil_print("dry-run: would have touched %d file(s)\n",
changeCount);
}else{
fossil_print("Touched %d file(s)\n", changeCount);
}
}
/*
** Returns non-zero if the specified file name ends with any reserved name,
** e.g.: _FOSSIL_ or .fslckout. Specifically, it returns 1 for exact match
** or 2 for a tail match on a longer file name.
**
** For the sake of efficiency, zFilename must be a canonical name, e.g. an
** absolute path using only forward slash ('/') as a directory separator.
**
** nFilename must be the length of zFilename. When negative, strlen() will
** be used to calculate it.
*/
int file_is_reserved_name(const char *zFilename, int nFilename){
const char *zEnd; /* one-after-the-end of zFilename */
int gotSuffix = 0; /* length of suffix (-wal, -shm, -journal) */
assert( zFilename && "API misuse" );
if( nFilename<0 ) nFilename = (int)strlen(zFilename);
if( nFilename<8 ) return 0; /* strlen("_FOSSIL_") */
zEnd = zFilename + nFilename;
if( nFilename>=12 ){ /* strlen("_FOSSIL_-(shm|wal)") */
/* Check for (-wal, -shm, -journal) suffixes, with an eye towards
** runtime speed. */
if( zEnd[-4]=='-' ){
if( fossil_strnicmp("wal", &zEnd[-3], 3)
&& fossil_strnicmp("shm", &zEnd[-3], 3) ){
return 0;
}
gotSuffix = 4;
}else if( nFilename>=16 && zEnd[-8]=='-' ){ /*strlen(_FOSSIL_-journal) */
if( fossil_strnicmp("journal", &zEnd[-7], 7) ) return 0;
gotSuffix = 8;
}
if( gotSuffix ){
assert( 4==gotSuffix || 8==gotSuffix );
zEnd -= gotSuffix;
nFilename -= gotSuffix;
gotSuffix = 1;
}
assert( nFilename>=8 && "strlen(_FOSSIL_)" );
assert( gotSuffix==0 || gotSuffix==1 );
}
switch( zEnd[-1] ){
case '_':{
if( fossil_strnicmp("_FOSSIL_", &zEnd[-8], 8) ) return 0;
if( 8==nFilename ) return 1;
return zEnd[-9]=='/' ? 2 : gotSuffix;
}
case 'T':
case 't':{
if( nFilename<9 || zEnd[-9]!='.'
|| fossil_strnicmp(".fslckout", &zEnd[-9], 9) ){
return 0;
}
if( 9==nFilename ) return 1;
return zEnd[-10]=='/' ? 2 : gotSuffix;
}
default:{
return 0;
}
}
}
/*
** COMMAND: test-is-reserved-name
**
** Usage: %fossil test-is-ckout-db FILENAMES...
**
** Passes each given name to file_is_reserved_name() and outputs one
** line per file: the result value of that function followed by the
** name.
*/
void test_is_reserved_name_cmd(void){
int i;
if(g.argc<3){
usage("FILENAME_1 [...FILENAME_N]");
}
for( i = 2; i < g.argc; ++i ){
const int check = file_is_reserved_name(g.argv[i], -1);
fossil_print("%d %s\n", check, g.argv[i]);
}
}
|
Changes to src/http.c.
| ︙ | ︙ | |||
373 374 375 376 377 378 379 380 381 382 383 384 385 |
j = strlen(zLine) - 1;
while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
j -= 4;
zLine[j] = 0;
}
if( (mHttpFlags & HTTP_QUIET)==0 ){
fossil_print("redirect with status %d to %s\n", rc, &zLine[i]);
}
wasHttps = g.url.isHttps;
url_parse(&zLine[i], 0);
if( wasHttps && !g.url.isHttps ){
fossil_warning("cannot redirect from HTTPS to HTTP");
goto write_err;
| > > > > > | > > > > | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
j = strlen(zLine) - 1;
while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
j -= 4;
zLine[j] = 0;
}
if( (mHttpFlags & HTTP_QUIET)==0 ){
fossil_print("redirect with status %d to %s\n", rc, &zLine[i]);
}
if( g.url.isFile || g.url.isSsh ){
fossil_warning("cannot redirect from %s to %s", g.url.canonical,
&zLine[i]);
goto write_err;
}
wasHttps = g.url.isHttps;
url_parse(&zLine[i], 0);
if( wasHttps && !g.url.isHttps ){
fossil_warning("cannot redirect from HTTPS to HTTP");
goto write_err;
}
if( g.url.isSsh || g.url.isFile ){
fossil_warning("cannot redirect to %s", &zLine[i]);
goto write_err;
}
transport_close(&g.url);
transport_global_shutdown(&g.url);
fSeenHttpAuth = 0;
if( g.zHttpAuth ) free(g.zHttpAuth);
g.zHttpAuth = get_httpauth();
if( rc==301 || rc==308 ) url_remember();
return http_exchange(pSend, pReply, mHttpFlags,
|
| ︙ | ︙ |
Changes to src/json_config.c.
| ︙ | ︙ | |||
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
{ "clean-glob", CONFIGSET_PROJ },
{ "ignore-glob", CONFIGSET_PROJ },
{ "keep-glob", CONFIGSET_PROJ },
{ "crlf-glob", CONFIGSET_PROJ },
{ "crnl-glob", CONFIGSET_PROJ },
{ "encoding-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
{ "allow-symlinks", CONFIGSET_PROJ },
{ "dotfiles", CONFIGSET_PROJ },
{ "ticket-table", CONFIGSET_TKT },
{ "ticket-common", CONFIGSET_TKT },
{ "ticket-change", CONFIGSET_TKT },
{ "ticket-newpage", CONFIGSET_TKT },
{ "ticket-viewpage", CONFIGSET_TKT },
| > > | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
{ "clean-glob", CONFIGSET_PROJ },
{ "ignore-glob", CONFIGSET_PROJ },
{ "keep-glob", CONFIGSET_PROJ },
{ "crlf-glob", CONFIGSET_PROJ },
{ "crnl-glob", CONFIGSET_PROJ },
{ "encoding-glob", CONFIGSET_PROJ },
{ "empty-dirs", CONFIGSET_PROJ },
#ifdef FOSSIL_LEGACY_ALLOW_SYMLINKS
{ "allow-symlinks", CONFIGSET_PROJ },
#endif
{ "dotfiles", CONFIGSET_PROJ },
{ "ticket-table", CONFIGSET_TKT },
{ "ticket-common", CONFIGSET_TKT },
{ "ticket-change", CONFIGSET_TKT },
{ "ticket-newpage", CONFIGSET_TKT },
{ "ticket-viewpage", CONFIGSET_TKT },
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 | blob_append(pOut, "UNICODE_COMMAND_LINE\n", -1); #endif #if defined(FOSSIL_DYNAMIC_BUILD) blob_append(pOut, "FOSSIL_DYNAMIC_BUILD\n", -1); #else blob_append(pOut, "FOSSIL_STATIC_BUILD\n", -1); #endif #if defined(HAVE_PLEDGE) blob_append(pOut, "HAVE_PLEDGE\n", -1); #endif #if defined(USE_MMAN_H) blob_append(pOut, "USE_MMAN_H\n", -1); #endif #if defined(USE_SEE) | > > > | 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 | blob_append(pOut, "UNICODE_COMMAND_LINE\n", -1); #endif #if defined(FOSSIL_DYNAMIC_BUILD) blob_append(pOut, "FOSSIL_DYNAMIC_BUILD\n", -1); #else blob_append(pOut, "FOSSIL_STATIC_BUILD\n", -1); #endif #if defined(FOSSIL_LEGACY_ALLOW_SYMLINKS) blob_append(pOut, "FOSSIL_LEGACY_ALLOW_SYMLINKS\n", -1); #endif #if defined(HAVE_PLEDGE) blob_append(pOut, "HAVE_PLEDGE\n", -1); #endif #if defined(USE_MMAN_H) blob_append(pOut, "USE_MMAN_H\n", -1); #endif #if defined(USE_SEE) |
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
585 586 587 588 589 590 591 592 593 594 595 596 597 598 |
** is when the specific event is said to occur.
*/
case 'E': {
if( p->rEventDate>0.0 ) SYNTAX("more than one E-card");
p->rEventDate = db_double(0.0,"SELECT julianday(%Q)", next_token(&x,0));
if( p->rEventDate<=0.0 ) SYNTAX("malformed date on E-card");
p->zEventId = next_token(&x, &sz);
if( !hname_validate(p->zEventId, sz) ){
SYNTAX("malformed hash on E-card");
}
p->type = CFTYPE_EVENT;
break;
}
| > | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 |
** is when the specific event is said to occur.
*/
case 'E': {
if( p->rEventDate>0.0 ) SYNTAX("more than one E-card");
p->rEventDate = db_double(0.0,"SELECT julianday(%Q)", next_token(&x,0));
if( p->rEventDate<=0.0 ) SYNTAX("malformed date on E-card");
p->zEventId = next_token(&x, &sz);
if( p->zEventId==0 ) SYNTAX("missing hash on E-card");
if( !hname_validate(p->zEventId, sz) ){
SYNTAX("malformed hash on E-card");
}
p->type = CFTYPE_EVENT;
break;
}
|
| ︙ | ︙ | |||
609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 |
if( zName==0 ) SYNTAX("missing filename on F-card");
defossilize(zName);
if( !file_is_simple_pathname_nonstrict(zName) ){
SYNTAX("F-card filename is not a simple path");
}
zUuid = next_token(&x, &sz);
if( p->zBaseline==0 || zUuid!=0 ){
if( !hname_validate(zUuid,sz) ){
SYNTAX("F-card hash invalid");
}
}
zPerm = next_token(&x,0);
zPriorName = next_token(&x,0);
if( zPriorName ){
defossilize(zPriorName);
if( !file_is_simple_pathname_nonstrict(zPriorName) ){
SYNTAX("F-card old filename is not a simple path");
}
}
if( p->nFile>=p->nFileAlloc ){
p->nFileAlloc = p->nFileAlloc*2 + 10;
p->aFile = fossil_realloc(p->aFile,
p->nFileAlloc*sizeof(p->aFile[0]) );
}
i = p->nFile++;
p->aFile[i].zName = zName;
p->aFile[i].zUuid = zUuid;
p->aFile[i].zPerm = zPerm;
p->aFile[i].zPrior = zPriorName;
| > > > > > > > > > > > < < < | 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 |
if( zName==0 ) SYNTAX("missing filename on F-card");
defossilize(zName);
if( !file_is_simple_pathname_nonstrict(zName) ){
SYNTAX("F-card filename is not a simple path");
}
zUuid = next_token(&x, &sz);
if( p->zBaseline==0 || zUuid!=0 ){
if( zUuid==0 ) SYNTAX("missing hash on F-card");
if( !hname_validate(zUuid,sz) ){
SYNTAX("F-card hash invalid");
}
}
zPerm = next_token(&x,0);
zPriorName = next_token(&x,0);
if( zPriorName ){
defossilize(zPriorName);
if( !file_is_simple_pathname_nonstrict(zPriorName) ){
SYNTAX("F-card old filename is not a simple path");
}
}
if( p->nFile>=p->nFileAlloc ){
p->nFileAlloc = p->nFileAlloc*2 + 10;
p->aFile = fossil_realloc(p->aFile,
p->nFileAlloc*sizeof(p->aFile[0]) );
}
i = p->nFile++;
if( i>0 && fossil_strcmp(p->aFile[i-1].zName, zName)>=0 ){
SYNTAX("incorrect F-card sort order");
}
if( file_is_reserved_name(zName,-1) ){
/* If reserved names leaked into historical manifests due to
** slack oversight by older versions of Fossil, simply ignore
** those files */
p->nFile--;
break;
}
p->aFile[i].zName = zName;
p->aFile[i].zUuid = zUuid;
p->aFile[i].zPerm = zPerm;
p->aFile[i].zPrior = zPriorName;
p->type = CFTYPE_MANIFEST;
break;
}
/*
** G <hash>
**
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
227 228 229 230 231 232 233 |
return rc;
}
/*
** Activate the query authorizer
*/
void report_restrict_sql(char **pzErr){
| | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
return rc;
}
/*
** Activate the query authorizer
*/
void report_restrict_sql(char **pzErr){
db_set_authorizer(report_query_authorizer,(void*)pzErr,"Ticket-Report");
sqlite3_limit(g.db, SQLITE_LIMIT_VDBE_OP, 10000);
}
void report_unrestrict_sql(void){
db_clear_authorizer();
}
/*
** Check the given SQL to see if is a valid query that does not
** attempt to do anything dangerous. Return 0 on success and a
** pointer to an error message string (obtained from malloc) if
|
| ︙ | ︙ | |||
677 678 679 680 681 682 683 |
/* Do initialization
*/
if( pState->nCount==0 ){
/* Turn off the authorizer. It is no longer doing anything since the
** query has already been prepared.
*/
| | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 |
/* Do initialization
*/
if( pState->nCount==0 ){
/* Turn off the authorizer. It is no longer doing anything since the
** query has already been prepared.
*/
db_clear_authorizer();
/* Figure out the number of columns, the column that determines background
** color, and whether or not this row of data is represented by multiple
** rows in the table.
*/
pState->nCol = 0;
pState->isMultirow = 0;
|
| ︙ | ︙ |
Changes to src/stash.c.
| ︙ | ︙ | |||
332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
db_multi_exec("INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)", zNew);
db_ephemeral_blob(&q, 6, &delta);
blob_write_to_file(&delta, zNPath);
file_setexe(zNPath, isExec);
}else if( isRemoved ){
fossil_print("DELETE %s\n", zOrig);
file_delete(zOPath);
}else{
Blob a, b, out, disk;
int isNewLink = file_islink(zOPath);
db_ephemeral_blob(&q, 6, &delta);
blob_read_from_file(&disk, zOPath, RepoFILE);
content_get(rid, &a);
blob_delta_apply(&a, &delta, &b);
| > > | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
db_multi_exec("INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)", zNew);
db_ephemeral_blob(&q, 6, &delta);
blob_write_to_file(&delta, zNPath);
file_setexe(zNPath, isExec);
}else if( isRemoved ){
fossil_print("DELETE %s\n", zOrig);
file_delete(zOPath);
}else if( file_unsafe_in_tree_path(zNPath) ){
/* Ignore the unsafe path */
}else{
Blob a, b, out, disk;
int isNewLink = file_islink(zOPath);
db_ephemeral_blob(&q, 6, &delta);
blob_read_from_file(&disk, zOPath, RepoFILE);
content_get(rid, &a);
blob_delta_apply(&a, &delta, &b);
|
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
int ticket_change(const char *zUuid){
const char *zConfig;
Th_FossilInit(TH_INIT_DEFAULT);
Th_Store("uuid", zUuid);
zConfig = ticket_change_code();
return Th_Eval(g.interp, 0, zConfig, -1);
}
/*
** Recreate the TICKET and TICKETCHNG tables.
*/
void ticket_create_table(int separateConnection){
const char *zSql;
db_multi_exec(
"DROP TABLE IF EXISTS ticket;"
"DROP TABLE IF EXISTS ticketchng;"
);
zSql = ticket_table_schema();
if( separateConnection ){
if( db_transaction_nesting_depth() ) db_end_transaction(0);
db_init_database(g.zRepositoryName, zSql, 0);
}else{
db_multi_exec("%s", zSql/*safe-for-%s*/);
}
}
/*
** Repopulate the TICKET and TICKETCHNG tables from scratch using all
** available ticket artifacts.
*/
void ticket_rebuild(void){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
int ticket_change(const char *zUuid){
const char *zConfig;
Th_FossilInit(TH_INIT_DEFAULT);
Th_Store("uuid", zUuid);
zConfig = ticket_change_code();
return Th_Eval(g.interp, 0, zConfig, -1);
}
/*
** An authorizer function for the SQL used to initialize the
** schema for the ticketing system. Only allow CREATE TABLE and
** CREATE INDEX for tables whose names begin with "ticket" and
** changes to tables whose names begin with "ticket".
*/
static int ticket_schema_auth(
void *pNErr,
int eCode,
const char *z0,
const char *z1,
const char *z2,
const char *z3
){
switch( eCode ){
case SQLITE_CREATE_TABLE: {
if( sqlite3_stricmp(z2,"main")!=0
&& sqlite3_stricmp(z2,"repository")!=0
){
goto ticket_schema_error;
}
if( sqlite3_strnicmp(z0,"ticket",6)!=0 ){
goto ticket_schema_error;
}
break;
}
case SQLITE_CREATE_INDEX: {
if( sqlite3_stricmp(z2,"main")!=0
&& sqlite3_stricmp(z2,"repository")!=0
){
goto ticket_schema_error;
}
if( sqlite3_strnicmp(z1,"ticket",6)!=0 ){
goto ticket_schema_error;
}
break;
}
case SQLITE_INSERT:
case SQLITE_UPDATE:
case SQLITE_DELETE: {
if( sqlite3_stricmp(z2,"main")!=0
&& sqlite3_stricmp(z2,"repository")!=0
){
goto ticket_schema_error;
}
if( sqlite3_strnicmp(z0,"ticket",6)!=0
&& sqlite3_strnicmp(z0,"sqlite_",7)!=0
){
goto ticket_schema_error;
}
break;
}
case SQLITE_REINDEX:
case SQLITE_TRANSACTION:
case SQLITE_READ: {
break;
}
default: {
goto ticket_schema_error;
}
}
return SQLITE_OK;
ticket_schema_error:
if( pNErr ) *(int*)pNErr = 1;
return SQLITE_DENY;
}
/*
** Recreate the TICKET and TICKETCHNG tables.
*/
void ticket_create_table(int separateConnection){
const char *zSql;
db_multi_exec(
"DROP TABLE IF EXISTS ticket;"
"DROP TABLE IF EXISTS ticketchng;"
);
zSql = ticket_table_schema();
if( separateConnection ){
if( db_transaction_nesting_depth() ) db_end_transaction(0);
db_set_authorizer(ticket_schema_auth,0,"Ticket-Schema");
db_init_database(g.zRepositoryName, zSql, 0);
}else{
db_set_authorizer(ticket_schema_auth,0,"Ticket-Schema");
db_multi_exec("%s", zSql/*safe-for-%s*/);
}
db_clear_authorizer();
}
/*
** Repopulate the TICKET and TICKETCHNG tables from scratch using all
** available ticket artifacts.
*/
void ticket_rebuild(void){
|
| ︙ | ︙ |
Changes to src/undo.c.
| ︙ | ︙ | |||
50 51 52 53 54 55 56 |
int new_exists;
int old_exe;
int new_exe;
int new_link;
int old_link;
Blob current;
Blob new;
| | > > | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
int new_exists;
int old_exe;
int new_exe;
int new_link;
int old_link;
Blob current;
Blob new;
zFullname = mprintf("%s%s", g.zLocalRoot, zPathname);
old_link = db_column_int(&q, 3);
new_exists = file_size(zFullname, RepoFILE)>=0;
new_link = file_islink(0);
if( new_exists ){
blob_read_from_file(¤t, zFullname, RepoFILE);
new_exe = file_isexe(0,0);
}else{
blob_zero(¤t);
new_exe = 0;
}
blob_zero(&new);
old_exists = db_column_int(&q, 1);
old_exe = db_column_int(&q, 2);
if( old_exists ){
db_ephemeral_blob(&q, 0, &new);
}
if( file_unsafe_in_tree_path(zFullname) ){
/* do nothign with this unsafe file */
}else if( old_exists ){
if( new_exists ){
fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname);
}else{
fossil_print("NEW %s\n", zPathname);
}
if( new_exists && (new_link || old_link) ){
file_delete(zFullname);
|
| ︙ | ︙ |
Changes to src/update.c.
| ︙ | ︙ | |||
866 867 868 869 870 871 872 873 874 875 876 877 878 879 |
db_multi_exec(
"UPDATE OR REPLACE vfile"
" SET pathname=origname, origname=NULL"
" WHERE pathname=%Q AND origname!=pathname;"
"DELETE FROM vfile WHERE pathname=%Q",
zFile, zFile
);
}else{
sqlite3_int64 mtime;
int rvChnged = 0;
int rvPerm = manifest_file_mperm(pRvFile);
/* Determine if reverted-to file is different than checked out file. */
if( pCoManifest && (pCoFile = manifest_file_find(pCoManifest, zFile)) ){
| > > | 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 |
db_multi_exec(
"UPDATE OR REPLACE vfile"
" SET pathname=origname, origname=NULL"
" WHERE pathname=%Q AND origname!=pathname;"
"DELETE FROM vfile WHERE pathname=%Q",
zFile, zFile
);
}else if( file_unsafe_in_tree_path(zFull) ){
/* Ignore this file */
}else{
sqlite3_int64 mtime;
int rvChnged = 0;
int rvPerm = manifest_file_mperm(pRvFile);
/* Determine if reverted-to file is different than checked out file. */
if( pCoManifest && (pCoFile = manifest_file_find(pCoManifest, zFile)) ){
|
| ︙ | ︙ |
Changes to src/vfile.c.
| ︙ | ︙ | |||
311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
const char *zName;
id = db_column_int(&q, 0);
zName = db_column_text(&q, 1);
rid = db_column_int(&q, 2);
isExe = db_column_int(&q, 3);
isLink = db_column_int(&q, 4);
content_get(rid, &content);
if( file_is_the_same(&content, zName) ){
blob_reset(&content);
if( file_setexe(zName, isExe) ){
db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
file_mtime(zName, RepoFILE), id);
}
| > > > | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
const char *zName;
id = db_column_int(&q, 0);
zName = db_column_text(&q, 1);
rid = db_column_int(&q, 2);
isExe = db_column_int(&q, 3);
isLink = db_column_int(&q, 4);
if( file_unsafe_in_tree_path(zName) ){
continue;
}
content_get(rid, &content);
if( file_is_the_same(&content, zName) ){
blob_reset(&content);
if( file_setexe(zName, isExe) ){
db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
file_mtime(zName, RepoFILE), id);
}
|
| ︙ | ︙ |