Fossil SCM

Amend [9919dfbbaa], again: Include an optional directory separator in buffer size calculation, guard against the unlikely (impossible?) case that a case-adjusted filename component round-tripping from UTF-8 to UTF-16 and back get longer, plus some unrelated white space fix.

florian 2024-10-16 05:16 trunk
Commit 49262642f421900cab3f58bf913417176410d036d0d06b19f17f6a8433d01265
1 file changed +12 -8
+12 -8
--- src/winfile.c
+++ src/winfile.c
@@ -349,17 +349,17 @@
349349
const char *zBase,
350350
const char *zPath
351351
){
352352
int cchBase = strlen(zBase);
353353
int cchPath = strlen(zPath);
354
- int cchBuf = cchBase + cchPath + 1;
355
- int cchRes = cchPath + 1;
354
+ int cchBuf = cchBase + cchPath + 2; /* + NULL + optional directory slash */
355
+ int cchRes = cchPath + 1; /* + NULL */
356356
char *zBuf = fossil_malloc(cchBuf);
357357
char *zRes = fossil_malloc(cchRes);
358
+ int ncUsed = 0;
358359
int i, j;
359360
memcpy(zBuf,zBase,cchBase);
360
- cchRes = 0;
361361
if( !IS_DIRSEP(zBuf,cchBase-1) ){
362362
zBuf[cchBase++]=L'/';
363363
}
364364
memcpy(zBuf+cchBase,zPath,cchPath+1);
365365
i = j = cchBase;
@@ -371,21 +371,21 @@
371371
char *zComp = &zBuf[i];
372372
int cchComp;
373373
char chSep;
374374
int fDone;
375375
if( IS_DIRSEP(zBuf,i) ){
376
- zRes[cchRes++] = zBuf[i];
376
+ zRes[ncUsed++] = zBuf[i];
377377
i = j = i+1;
378378
continue;
379379
}
380380
NEXT_DIRSEP(zBuf,j);
381381
fDone = zBuf[j]==0;
382382
chSep = zBuf[j];
383383
zBuf[j] = 0; /* Truncate working buffer. */
384384
wzBuf = fossil_utf8_to_path(zBuf,0);
385385
hFind = FindFirstFileW(wzBuf,&fd);
386
- if( hFind!= INVALID_HANDLE_VALUE ){
386
+ if( hFind!=INVALID_HANDLE_VALUE ){
387387
wchar_t *wzComp = fossil_utf8_to_path(zComp,0);
388388
FindClose(hFind);
389389
/* Test fd.cFileName, not fd.cAlternateFileName (classic 8.3 format). */
390390
if( win32_compare_filenames_nocase(wzComp,fd.cFileName)==0 ){
391391
zCompBuf = fossil_path_to_utf8(fd.cFileName);
@@ -393,21 +393,25 @@
393393
}
394394
fossil_path_free(wzComp);
395395
}
396396
fossil_path_free(wzBuf);
397397
cchComp = strlen(zComp);
398
- memcpy(zRes+cchRes,zComp,cchComp);
399
- cchRes += cchComp;
398
+ if( ncUsed+cchComp+1>cchRes ){
399
+ cchRes = ncUsed + cchComp + 32; /* While at it, add some extra space. */
400
+ zRes = fossil_realloc(zRes,cchRes);
401
+ }
402
+ memcpy(zRes+ncUsed,zComp,cchComp);
403
+ ncUsed += cchComp;
400404
if( zCompBuf ){
401405
fossil_path_free(zCompBuf);
402406
}
403407
if( fDone ){
404
- zRes[cchRes] = 0;
408
+ zRes[ncUsed] = 0;
405409
break;
406410
}
407411
zBuf[j] = chSep; /* Undo working buffer truncation. */
408412
i = j;
409413
}
410414
fossil_free(zBuf);
411415
return zRes;
412416
}
413417
#endif /* _WIN32 -- This code is for win32 only */
414418
--- src/winfile.c
+++ src/winfile.c
@@ -349,17 +349,17 @@
349 const char *zBase,
350 const char *zPath
351 ){
352 int cchBase = strlen(zBase);
353 int cchPath = strlen(zPath);
354 int cchBuf = cchBase + cchPath + 1;
355 int cchRes = cchPath + 1;
356 char *zBuf = fossil_malloc(cchBuf);
357 char *zRes = fossil_malloc(cchRes);
 
358 int i, j;
359 memcpy(zBuf,zBase,cchBase);
360 cchRes = 0;
361 if( !IS_DIRSEP(zBuf,cchBase-1) ){
362 zBuf[cchBase++]=L'/';
363 }
364 memcpy(zBuf+cchBase,zPath,cchPath+1);
365 i = j = cchBase;
@@ -371,21 +371,21 @@
371 char *zComp = &zBuf[i];
372 int cchComp;
373 char chSep;
374 int fDone;
375 if( IS_DIRSEP(zBuf,i) ){
376 zRes[cchRes++] = zBuf[i];
377 i = j = i+1;
378 continue;
379 }
380 NEXT_DIRSEP(zBuf,j);
381 fDone = zBuf[j]==0;
382 chSep = zBuf[j];
383 zBuf[j] = 0; /* Truncate working buffer. */
384 wzBuf = fossil_utf8_to_path(zBuf,0);
385 hFind = FindFirstFileW(wzBuf,&fd);
386 if( hFind!= INVALID_HANDLE_VALUE ){
387 wchar_t *wzComp = fossil_utf8_to_path(zComp,0);
388 FindClose(hFind);
389 /* Test fd.cFileName, not fd.cAlternateFileName (classic 8.3 format). */
390 if( win32_compare_filenames_nocase(wzComp,fd.cFileName)==0 ){
391 zCompBuf = fossil_path_to_utf8(fd.cFileName);
@@ -393,21 +393,25 @@
393 }
394 fossil_path_free(wzComp);
395 }
396 fossil_path_free(wzBuf);
397 cchComp = strlen(zComp);
398 memcpy(zRes+cchRes,zComp,cchComp);
399 cchRes += cchComp;
 
 
 
 
400 if( zCompBuf ){
401 fossil_path_free(zCompBuf);
402 }
403 if( fDone ){
404 zRes[cchRes] = 0;
405 break;
406 }
407 zBuf[j] = chSep; /* Undo working buffer truncation. */
408 i = j;
409 }
410 fossil_free(zBuf);
411 return zRes;
412 }
413 #endif /* _WIN32 -- This code is for win32 only */
414
--- src/winfile.c
+++ src/winfile.c
@@ -349,17 +349,17 @@
349 const char *zBase,
350 const char *zPath
351 ){
352 int cchBase = strlen(zBase);
353 int cchPath = strlen(zPath);
354 int cchBuf = cchBase + cchPath + 2; /* + NULL + optional directory slash */
355 int cchRes = cchPath + 1; /* + NULL */
356 char *zBuf = fossil_malloc(cchBuf);
357 char *zRes = fossil_malloc(cchRes);
358 int ncUsed = 0;
359 int i, j;
360 memcpy(zBuf,zBase,cchBase);
 
361 if( !IS_DIRSEP(zBuf,cchBase-1) ){
362 zBuf[cchBase++]=L'/';
363 }
364 memcpy(zBuf+cchBase,zPath,cchPath+1);
365 i = j = cchBase;
@@ -371,21 +371,21 @@
371 char *zComp = &zBuf[i];
372 int cchComp;
373 char chSep;
374 int fDone;
375 if( IS_DIRSEP(zBuf,i) ){
376 zRes[ncUsed++] = zBuf[i];
377 i = j = i+1;
378 continue;
379 }
380 NEXT_DIRSEP(zBuf,j);
381 fDone = zBuf[j]==0;
382 chSep = zBuf[j];
383 zBuf[j] = 0; /* Truncate working buffer. */
384 wzBuf = fossil_utf8_to_path(zBuf,0);
385 hFind = FindFirstFileW(wzBuf,&fd);
386 if( hFind!=INVALID_HANDLE_VALUE ){
387 wchar_t *wzComp = fossil_utf8_to_path(zComp,0);
388 FindClose(hFind);
389 /* Test fd.cFileName, not fd.cAlternateFileName (classic 8.3 format). */
390 if( win32_compare_filenames_nocase(wzComp,fd.cFileName)==0 ){
391 zCompBuf = fossil_path_to_utf8(fd.cFileName);
@@ -393,21 +393,25 @@
393 }
394 fossil_path_free(wzComp);
395 }
396 fossil_path_free(wzBuf);
397 cchComp = strlen(zComp);
398 if( ncUsed+cchComp+1>cchRes ){
399 cchRes = ncUsed + cchComp + 32; /* While at it, add some extra space. */
400 zRes = fossil_realloc(zRes,cchRes);
401 }
402 memcpy(zRes+ncUsed,zComp,cchComp);
403 ncUsed += cchComp;
404 if( zCompBuf ){
405 fossil_path_free(zCompBuf);
406 }
407 if( fDone ){
408 zRes[ncUsed] = 0;
409 break;
410 }
411 zBuf[j] = chSep; /* Undo working buffer truncation. */
412 i = j;
413 }
414 fossil_free(zBuf);
415 return zRes;
416 }
417 #endif /* _WIN32 -- This code is for win32 only */
418

Keyboard Shortcuts

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