Index: src/db.c ================================================================== --- src/db.c +++ src/db.c @@ -3926,10 +3926,21 @@ ** to obtain a check-in lock during auto-sync, the server will ** send the "pragma avoid-delta-manifests" statement in its reply, ** which will cause the client to avoid generating a delta ** manifest. */ +/* +** SETTING: permissive-manifest-parser boolean default=off sensitive +** By default, fossil fatally fails if any files are found in a +** manifest which have a name matching a checkout database name. In +** order to support repositories where such files were inadvertently +** checked in, this setting, when on, allows such files to be handled +** as if they were normal files. Only enable this if absolutely +** necessary to support older repositories which have such files +** checked in (anywhere in their history). It should never be enabled +** for new repositories or old ones which do not contain such files. +*/ /* ** SETTING: proxy width=32 default=off ** URL of the HTTP proxy. If undefined or "off" then ** the "http_proxy" environment variable is consulted. ** If the http_proxy environment variable is undefined Index: src/file.c ================================================================== --- src/file.c +++ src/file.c @@ -2516,11 +2516,11 @@ } /* ** COMMAND: test-is-reserved-name ** -** Usage: %fossil test-is-ckout-db FILENAMES... +** Usage: %fossil test-is-reserved-name 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. */ Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -220,10 +220,14 @@ int noPswd; /* Logged in without password (on 127.0.0.1) */ int userUid; /* Integer user id */ int isHuman; /* True if access by a human, not a spider or bot */ int comFmtFlags; /* Zero or more "COMMENT_PRINT_*" bit flags, should be ** accessed through get_comment_format(). */ + int permissiveManifest; /* Tells manifest_parser() whether it may run in + ** "permissive" (compatibilty) mode. <0=not yet determined, + ** 0=no, >0=yes. MUST be set to a negative value early on + ** in app-init (before CLI flags are processed). */ /* Information used to populate the RCVFROM table */ int rcvid; /* The rcvid. 0 if not yet defined. */ char *zIpAddr; /* The remote IP address */ char *zNonce; /* The nonce used for login */ @@ -683,10 +687,11 @@ sqlite3_config(SQLITE_CONFIG_MULTITHREAD); sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); memset(&g, 0, sizeof(g)); g.now = time(0); g.httpHeader = empty_blob; + g.permissiveManifest = -1; #ifdef FOSSIL_ENABLE_JSON #if defined(NDEBUG) g.json.errorDetailParanoia = 2 /* FIXME: make configurable One problem we have here is that this code is needed before the db is opened, Index: src/manifest.c ================================================================== --- src/manifest.c +++ src/manifest.c @@ -454,11 +454,14 @@ isRepeat = 1; }else{ isRepeat = 0; bag_insert(&seenManifests, rid); } - + if(g.permissiveManifest<0){ + g.permissiveManifest = + db_get_boolean("permissive-manifest-parser", 0); + } /* Every structural artifact ends with a '\n' character. Exit early ** if that is not the case for this artifact. */ if( !isRepeat ) g.parseCnt[0]++; z = blob_materialize(pContent); @@ -630,13 +633,16 @@ case 'F': { char *zName, *zPerm, *zPriorName; zName = next_token(&x,0); if( zName==0 ) SYNTAX("missing filename on F-card"); defossilize(zName); + assert(g.permissiveManifest>=0 + && "Must have been set at app init"); if( !file_is_simple_pathname_nonstrict(zName) ){ SYNTAX("F-card filename is not a simple path"); - }else if( file_is_reserved_name(zName,-1) ){ + }else if( g.permissiveManifest==0 + && file_is_reserved_name(zName,-1) ){ SYNTAX("F-card contains a reserved name"); } zUuid = next_token(&x, &sz); if( p->zBaseline==0 || zUuid!=0 ){ if( zUuid==0 ) SYNTAX("missing hash on F-card"); Index: src/rebuild.c ================================================================== --- src/rebuild.c +++ src/rebuild.c @@ -628,10 +628,17 @@ int optNoIndex; int optIndex; int optIfNeeded; int compressOnlyFlag; + g.permissiveManifest = 1 + /* We always allow permissive manifest parsing when mass-dealing + with batches which are likely to include historical, but no + longer used/relevant, manifests. Though rebuild will not fail + for bad manifests, it will consider them to be non-manifests, + so would necessarily elide them from the timeline. + */; omitVerify = find_option("noverify",0,0)!=0; forceFlag = find_option("force","f",0)!=0; randomizeFlag = find_option("randomize", 0, 0)!=0; doClustering = find_option("cluster", 0, 0)!=0; runVacuum = find_option("vacuum",0,0)!=0;