-C Improved\simplementation\sof\srealpath()\sin\sthe\sfileio.c\sextension\sthat\sdoes\snot\srequire\nthe\slast\selement\sof\sthe\spath\sto\sactually\sexist.
-D 2026-02-23T00:57:00.749
+C When\sdoing\san\sSQLAR\sarchive\sextraction\sin\sthe\sCLI,\spostpone\screating\ssymlinks\suntil\safter\nall\sfiles\sand\sdirectories\shave\sbeen\screated.\s\sThis\sprevents\sa\shostile\sarchive\sfrom\ncreating\sa\ssymlink\sthrough\swhich\sit\scan\ssubsequently\swrite\scontent\soutside\sof\sthe\starget\ndirectory.\s\s[forum:forumpost/9e176adfef91c207|Forum\spost\s9e176adfef91c207].
+D 2026-02-23T01:34:14.113
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F src/resolve.c 928ff887f2a7c64275182060d94d06fdddbe32226c569781cf7e7edc6f58d7fd
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 615d62112f5c14fb24facf9391492b42403875bfd4288db6ba10d7e6fbc22c4c
-F src/shell.c.in 3e87584890a4e9797865e4771689d8d1aca3b0f824f973192784716ecfa320a2
+F src/shell.c.in 096db72b94687e46d7805e96c2a28fd1525fc6735d8967b9ce37b0b9dbbb9c90
F src/sqlite.h.in c7582608c8270428b288a529f4a4170298a19548266b55edaa2e70ce8d607f0e
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 8bb8941930378b436f1353603be194644568b55fe347475be0caddddad40efa3
-R 655393f8c2d5cab161b45421e875ddda
+P 4df4999484d9008d8af3c9c340810e0cf5f57161ba053ed5501276b450577039
+R 536f614f7f299837eaceb0448191c5cb
U drh
-Z 730476000580ff31324acec73800a8e3
+Z 1a29d5706c125cd77c3ea8fb58018127
# Remove this line to create a well-formed Fossil manifest.
*/
static int arExtractCommand(ArCommand *pAr){
const char *zSql1 =
- "SELECT "
- " ($dir || name),"
- " writefile(($dir || name), %s, mode, mtime) "
- "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"
- " AND name NOT GLOB '*..[/\\]*'";
+ "SELECT ($dir || name),\n"
+ " writefile(($dir || name), %s, mode, mtime)\n"
+ " FROM %s\n"
+ " WHERE (%s)\n"
+ " AND NOT ((mode&0xf000)==0x8000 AND $pass>0)\n" /* Files on pass 0 */
+ " AND NOT (data IS NULL AND $pass==1)\n" /* Dirs on passes 0,2 */
+ " AND NOT ((mode&0xf000)==0xa000 AND $pass<>1)\n" /* Symlink on pass 1 */
+ " AND name NOT GLOB '*..[/\\]*'\n";
const char *azExtraArg[] = {
"sqlar_uncompress(data, sz)",
j = sqlite3_bind_parameter_index(pSql, "$dir");
sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
- /* Run the SELECT statement twice. The first time, writefile() is called
- ** for all archive members that should be extracted. The second time,
- ** only for the directories. This is because the timestamps for
- ** extracted directories must be reset after they are populated (as
- ** populating them changes the timestamp). */
- for(i=0; i<2; i++){
- j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
+ /* Run the SELECT statement thrice:
+ ** (1) writefile() all files and directories, but not symlinks
+ ** (2) writefile() for symlinks
+ ** (3) writefile() for directory again
+ ** Symlinks are created after everything else to prevent writing content
+ ** through a symlink that was created by the extraction.
+ ** The third pass is so that the timestamps for extracted directories
+ ** will be reset to the value in the archive, since populating them
+ ** in the previous passes will have changed the timestamp. */
+ for(i=0; i<3; i++){
+ j = sqlite3_bind_parameter_index(pSql, "$pass");
sqlite3_bind_int(pSql, j, i);
if( pAr->bDryRun ){
cli_printf(pAr->out, "%s\n", sqlite3_sql(pSql));
+ break;
}else{
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
if( i==0 && pAr->bVerbose ){