Fossil SCM

On windows, make sure temporary pathnames containing non-ASCII characters are handled correctly. Add the fossil_freopen() wrapper around freopen() for portability.

drh 2021-09-03 12:07 trunk merge
Commit f48e48f664de9bbf2a06550b9746fddf29320632efc70d42a5b69f5aff9487c0
+2 -2
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -282,11 +282,11 @@
282282
*/
283283
void diff_begin(u64 diffFlags){
284284
if( (diffFlags & DIFF_BROWSER)!=0 ){
285285
tempDiffFilename = fossil_temp_filename();
286286
tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename);
287
- diffOut = freopen(tempDiffFilename,"wb",stdout);
287
+ diffOut = fossil_freopen(tempDiffFilename,"wb",stdout);
288288
if( diffOut==0 ){
289289
fossil_fatal("unable to create temporary file \"%s\"",
290290
tempDiffFilename);
291291
}
292292
#ifndef _WIN32
@@ -326,11 +326,11 @@
326326
fossil_print("%s", zWebpageEnd);
327327
}
328328
if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){
329329
char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename);
330330
fclose(diffOut);
331
- diffOut = freopen(NULL_DEVICE, "wb", stdout);
331
+ diffOut = fossil_freopen(NULL_DEVICE, "wb", stdout);
332332
fossil_system(zCmd);
333333
fossil_free(zCmd);
334334
diffOut = 0;
335335
sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY);
336336
file_delete(tempDiffFilename);
337337
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -282,11 +282,11 @@
282 */
283 void diff_begin(u64 diffFlags){
284 if( (diffFlags & DIFF_BROWSER)!=0 ){
285 tempDiffFilename = fossil_temp_filename();
286 tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename);
287 diffOut = freopen(tempDiffFilename,"wb",stdout);
288 if( diffOut==0 ){
289 fossil_fatal("unable to create temporary file \"%s\"",
290 tempDiffFilename);
291 }
292 #ifndef _WIN32
@@ -326,11 +326,11 @@
326 fossil_print("%s", zWebpageEnd);
327 }
328 if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){
329 char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename);
330 fclose(diffOut);
331 diffOut = freopen(NULL_DEVICE, "wb", stdout);
332 fossil_system(zCmd);
333 fossil_free(zCmd);
334 diffOut = 0;
335 sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY);
336 file_delete(tempDiffFilename);
337
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -282,11 +282,11 @@
282 */
283 void diff_begin(u64 diffFlags){
284 if( (diffFlags & DIFF_BROWSER)!=0 ){
285 tempDiffFilename = fossil_temp_filename();
286 tempDiffFilename = sqlite3_mprintf("%z.html", tempDiffFilename);
287 diffOut = fossil_freopen(tempDiffFilename,"wb",stdout);
288 if( diffOut==0 ){
289 fossil_fatal("unable to create temporary file \"%s\"",
290 tempDiffFilename);
291 }
292 #ifndef _WIN32
@@ -326,11 +326,11 @@
326 fossil_print("%s", zWebpageEnd);
327 }
328 if( (diffFlags & DIFF_BROWSER)!=0 && nErr==0 ){
329 char *zCmd = mprintf("%s %$", fossil_web_browser(), tempDiffFilename);
330 fclose(diffOut);
331 diffOut = fossil_freopen(NULL_DEVICE, "wb", stdout);
332 fossil_system(zCmd);
333 fossil_free(zCmd);
334 diffOut = 0;
335 sqlite3_sleep(FOSSIL_BROWSER_DIFF_DELAY);
336 file_delete(tempDiffFilename);
337
+16
--- src/file.c
+++ src/file.c
@@ -2160,10 +2160,26 @@
21602160
#else
21612161
FILE *f = fopen(zName, zMode);
21622162
#endif
21632163
return f;
21642164
}
2165
+
2166
+/*
2167
+** Wrapper for freopen() that understands UTF8 arguments.
2168
+*/
2169
+FILE *fossil_freopen(const char *zName, const char *zMode, FILE *stream){
2170
+#ifdef _WIN32
2171
+ wchar_t *uMode = fossil_utf8_to_unicode(zMode);
2172
+ wchar_t *uName = fossil_utf8_to_path(zName, 0);
2173
+ FILE *f = _wfreopen(uName, uMode, stream);
2174
+ fossil_path_free(uName);
2175
+ fossil_unicode_free(uMode);
2176
+#else
2177
+ FILE *f = freopen(zName, zMode, stream);
2178
+#endif
2179
+ return f;
2180
+}
21652181
21662182
/*
21672183
** Works like fclose() except that:
21682184
**
21692185
** 1) is a no-op if f is 0 or if it is stdin.
21702186
--- src/file.c
+++ src/file.c
@@ -2160,10 +2160,26 @@
2160 #else
2161 FILE *f = fopen(zName, zMode);
2162 #endif
2163 return f;
2164 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2165
2166 /*
2167 ** Works like fclose() except that:
2168 **
2169 ** 1) is a no-op if f is 0 or if it is stdin.
2170
--- src/file.c
+++ src/file.c
@@ -2160,10 +2160,26 @@
2160 #else
2161 FILE *f = fopen(zName, zMode);
2162 #endif
2163 return f;
2164 }
2165
2166 /*
2167 ** Wrapper for freopen() that understands UTF8 arguments.
2168 */
2169 FILE *fossil_freopen(const char *zName, const char *zMode, FILE *stream){
2170 #ifdef _WIN32
2171 wchar_t *uMode = fossil_utf8_to_unicode(zMode);
2172 wchar_t *uName = fossil_utf8_to_path(zName, 0);
2173 FILE *f = _wfreopen(uName, uMode, stream);
2174 fossil_path_free(uName);
2175 fossil_unicode_free(uMode);
2176 #else
2177 FILE *f = freopen(zName, zMode, stream);
2178 #endif
2179 return f;
2180 }
2181
2182 /*
2183 ** Works like fclose() except that:
2184 **
2185 ** 1) is a no-op if f is 0 or if it is stdin.
2186
+1 -1
--- src/utf8.c
+++ src/utf8.c
@@ -88,11 +88,11 @@
8888
#endif
8989
}
9090
9191
/*
9292
** Deallocate any memory that was previously allocated by
93
-** fossil_unicode_to_utf8().
93
+** fossil_unicode_to_utf8() or fossil_utf8_to_unicode().
9494
*/
9595
void fossil_unicode_free(void *pOld){
9696
fossil_free(pOld);
9797
}
9898
9999
--- src/utf8.c
+++ src/utf8.c
@@ -88,11 +88,11 @@
88 #endif
89 }
90
91 /*
92 ** Deallocate any memory that was previously allocated by
93 ** fossil_unicode_to_utf8().
94 */
95 void fossil_unicode_free(void *pOld){
96 fossil_free(pOld);
97 }
98
99
--- src/utf8.c
+++ src/utf8.c
@@ -88,11 +88,11 @@
88 #endif
89 }
90
91 /*
92 ** Deallocate any memory that was previously allocated by
93 ** fossil_unicode_to_utf8() or fossil_utf8_to_unicode().
94 */
95 void fossil_unicode_free(void *pOld){
96 fossil_free(pOld);
97 }
98
99
+13 -6
--- src/util.c
+++ src/util.c
@@ -655,25 +655,28 @@
655655
char zSep[2];
656656
size_t nDir;
657657
u64 r[2];
658658
int i;
659659
#ifdef _WIN32
660
- char zTempDir[1000];
660
+ char *zTempDirA = NULL;
661
+ WCHAR zTempDirW[MAX_PATH+1];
662
+ const DWORD dwTempSizeW = sizeof(zTempDirW)/sizeof(zTempDirW[0]);
663
+ DWORD dwTempLenW;
661664
#else
662665
static const char *azTmp[] = {"/var/tmp","/usr/tmp","/tmp"};
663666
#endif
664667
if( g.db ){
665668
sqlite3_file_control(g.db, 0, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTFile);
666669
if( zTFile ) return zTFile;
667670
}
668671
sqlite3_randomness(sizeof(r), &r);
669672
#if _WIN32
670
- zTempDir[0] = 0;
671673
cDirSep = '\\';
672
- GetTempPathA(sizeof(zTempDir), zTempDir);
673
- if( zTempDir[0] ){
674
- zDir = zTempDir;
674
+ dwTempLenW = GetTempPathW(dwTempSizeW, zTempDirW);
675
+ if( dwTempLenW>0 && dwTempLenW<dwTempSizeW
676
+ && ( zTempDirA = fossil_path_to_utf8(zTempDirW) )){
677
+ zDir = zTempDirA;
675678
}else{
676679
zDir = fossil_getenv("LOCALAPPDATA");
677680
if( zDir==0 ) zDir = ".";
678681
}
679682
#else
@@ -688,11 +691,15 @@
688691
cDirSep = '/';
689692
#endif
690693
nDir = strlen(zDir);
691694
zSep[1] = 0;
692695
zSep[0] = (nDir && zDir[nDir-1]==cDirSep) ? 0 : cDirSep;
693
- return sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]);
696
+ zTFile = sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]);
697
+#ifdef _WIN32
698
+ if( zTempDirA ) fossil_path_free(zTempDirA);
699
+#endif
700
+ return zTFile;
694701
}
695702
696703
/*
697704
** Turn memory limits for stack and heap on and off. The argument
698705
** is true to turn memory limits on and false to turn them off.
699706
--- src/util.c
+++ src/util.c
@@ -655,25 +655,28 @@
655 char zSep[2];
656 size_t nDir;
657 u64 r[2];
658 int i;
659 #ifdef _WIN32
660 char zTempDir[1000];
 
 
 
661 #else
662 static const char *azTmp[] = {"/var/tmp","/usr/tmp","/tmp"};
663 #endif
664 if( g.db ){
665 sqlite3_file_control(g.db, 0, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTFile);
666 if( zTFile ) return zTFile;
667 }
668 sqlite3_randomness(sizeof(r), &r);
669 #if _WIN32
670 zTempDir[0] = 0;
671 cDirSep = '\\';
672 GetTempPathA(sizeof(zTempDir), zTempDir);
673 if( zTempDir[0] ){
674 zDir = zTempDir;
 
675 }else{
676 zDir = fossil_getenv("LOCALAPPDATA");
677 if( zDir==0 ) zDir = ".";
678 }
679 #else
@@ -688,11 +691,15 @@
688 cDirSep = '/';
689 #endif
690 nDir = strlen(zDir);
691 zSep[1] = 0;
692 zSep[0] = (nDir && zDir[nDir-1]==cDirSep) ? 0 : cDirSep;
693 return sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]);
 
 
 
 
694 }
695
696 /*
697 ** Turn memory limits for stack and heap on and off. The argument
698 ** is true to turn memory limits on and false to turn them off.
699
--- src/util.c
+++ src/util.c
@@ -655,25 +655,28 @@
655 char zSep[2];
656 size_t nDir;
657 u64 r[2];
658 int i;
659 #ifdef _WIN32
660 char *zTempDirA = NULL;
661 WCHAR zTempDirW[MAX_PATH+1];
662 const DWORD dwTempSizeW = sizeof(zTempDirW)/sizeof(zTempDirW[0]);
663 DWORD dwTempLenW;
664 #else
665 static const char *azTmp[] = {"/var/tmp","/usr/tmp","/tmp"};
666 #endif
667 if( g.db ){
668 sqlite3_file_control(g.db, 0, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTFile);
669 if( zTFile ) return zTFile;
670 }
671 sqlite3_randomness(sizeof(r), &r);
672 #if _WIN32
 
673 cDirSep = '\\';
674 dwTempLenW = GetTempPathW(dwTempSizeW, zTempDirW);
675 if( dwTempLenW>0 && dwTempLenW<dwTempSizeW
676 && ( zTempDirA = fossil_path_to_utf8(zTempDirW) )){
677 zDir = zTempDirA;
678 }else{
679 zDir = fossil_getenv("LOCALAPPDATA");
680 if( zDir==0 ) zDir = ".";
681 }
682 #else
@@ -688,11 +691,15 @@
691 cDirSep = '/';
692 #endif
693 nDir = strlen(zDir);
694 zSep[1] = 0;
695 zSep[0] = (nDir && zDir[nDir-1]==cDirSep) ? 0 : cDirSep;
696 zTFile = sqlite3_mprintf("%s%sfossil%016llx%016llx", zDir,zSep,r[0],r[1]);
697 #ifdef _WIN32
698 if( zTempDirA ) fossil_path_free(zTempDirA);
699 #endif
700 return zTFile;
701 }
702
703 /*
704 ** Turn memory limits for stack and heap on and off. The argument
705 ** is true to turn memory limits on and false to turn them off.
706

Keyboard Shortcuts

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