file_translateTildeInPath currently translates the first ~ it finds. This is different from shell which only translates it if it is the first character of a word and not if other letters follow.
As file_translateTildeInPath is always called with a single filename, only replace it if this string is "~" or starts with "~/". Additionally add an size argument to the function, so that no string buffers can overrun and do not access a NULL pointer if HOME is not set. --- gv/src/file.c | 27 ++++++++++++--------------- gv/src/file.h | 2 +- gv/src/main.c | 4 ++-- gv/src/resource.c | 10 +++++----- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/gv/src/file.c b/gv/src/file.c index 3bbd617..c33e683 100644 --- a/gv/src/file.c +++ b/gv/src/file.c @@ -173,7 +173,7 @@ file_getTmpFilename(const char *baseDirectory, const char *baseFilename, int *fi len, baseDirectory, tmpName, tmpExt); if (l < 0 || l >= sizeof(tempFilename) ) break; - file_translateTildeInPath(tempFilename); + file_translateTildeInPath(tempFilename, sizeof(tempFilename)); oldumask = umask(0077); fd = mkstemp(tempFilename); umask(oldumask); @@ -204,23 +204,20 @@ file_getTmpFilename(const char *baseDirectory, const char *baseFilename, int *fi /* Replaces tilde in string by user's home directory. */ /*############################################################*/ -void -file_translateTildeInPath(path) - char *path; +void file_translateTildeInPath(char *path, size_t s) { - char *pos; BEGINMESSAGE(file_translateTildeInPath) - if ((pos=strchr(path,'~'))) { - char *home; - char tmp[GV_MAX_FILENAME_LENGTH]; - home=getenv("HOME"); - if (strlen(home)+strlen(path)-1 < GV_MAX_FILENAME_LENGTH-1) { - *pos='\0'; pos++; - strcpy(tmp,path); - strcat(tmp,home); - strcat(tmp,pos); - strcpy(path,tmp); + if (path[0] == '~' && (path[1] == '/' || path[1] == '\0')) { + char *home = getenv("HOME"); + + if (home != NULL) { + size_t pl = strlen(path); + size_t hl = strlen(home); + if (pl + hl - 1 < s - 1) { + memmove(path + hl, path + 1, pl - 1 + 1); + memcpy(path, home, hl); + } } } ENDMESSAGE(file_translateTildeInPath) diff --git a/gv/src/file.h b/gv/src/file.h index 402c3ef..e479dab 100644 --- a/gv/src/file.h +++ b/gv/src/file.h @@ -36,7 +36,7 @@ extern char* file_getDirOfPath (char *); extern char* file_locateFilename (char *); extern char* file_getTmpFilename (const char *, const char *, int *); -extern void file_translateTildeInPath (char *); +extern void file_translateTildeInPath (char *, size_t); extern int file_fileIsDir (char *); extern int file_fileIsNotUseful (char *); extern char* file_pdfname2psname (char *); diff --git a/gv/src/main.c b/gv/src/main.c index dc2b773..74296c3 100644 --- a/gv/src/main.c +++ b/gv/src/main.c @@ -702,7 +702,7 @@ int main(argc, argv) char buffer[512]; strcpy(buffer, app_res.scratch_dir); strcat(buffer,"gv-safe-workdir-XXXXXX"); - file_translateTildeInPath(buffer); + file_translateTildeInPath(buffer, sizeof(buffer)); gv_safe_gs_workdir = strdup(mkdtemp(buffer)); gv_safe_gs_tempdir = 1; @@ -721,7 +721,7 @@ int main(argc, argv) char* tmp_savepos_filename; main_setInternResource(gv_database,&tmp_savepos_filename,"saveposFilename"); strcpy(gv_savepos_filename, tmp_savepos_filename); - file_translateTildeInPath(gv_savepos_filename); + file_translateTildeInPath(gv_savepos_filename, sizeof(gv_savepos_filename)); } main_setInternResource(gv_database,&gv_uncompress_command,"uncompressCommand"); diff --git a/gv/src/resource.c b/gv/src/resource.c index 5316485..1547542 100644 --- a/gv/src/resource.c +++ b/gv/src/resource.c @@ -175,7 +175,7 @@ resource_buildDatabase ( INFMESSAGE(checking for user resources) strcpy(tmp,USER_DEFAULTS); - file_translateTildeInPath(tmp); + file_translateTildeInPath(tmp, sizeof(tmp)); if (!file_fileIsNotUseful(tmp)) { s = XtNewString(tmp); tildeGv = USER_DEFAULTS; @@ -254,7 +254,7 @@ resource_buildDatabase ( strcpy(tmp,USER_DEFAULTS "-"); strcat(tmp, locale1); - file_translateTildeInPath(tmp); + file_translateTildeInPath(tmp, sizeof(tmp)); if (!stat(tmp, &buf)) { i18n = 1; @@ -304,7 +304,7 @@ resource_buildDatabase ( strcpy(tmp,USER_DEFAULTS "-"); strcat(tmp, locale2); - file_translateTildeInPath(tmp); + file_translateTildeInPath(tmp, sizeof(tmp)); if (!stat(tmp, &buf)) { i18n = 1; @@ -349,7 +349,7 @@ resource_buildDatabase ( strcpy(tmp,USER_DEFAULTS "-"); strcat(tmp, locale3); - file_translateTildeInPath(tmp); + file_translateTildeInPath(tmp, sizeof(tmp)); if (!stat(tmp, &buf)) { i18n = 1; @@ -874,7 +874,7 @@ static char* resource_mergeFileIntoDatabase(dbP,name) } strcpy(tmp,name); - file_translateTildeInPath(tmp); + file_translateTildeInPath(tmp, sizeof(tmp)); if (tmp[0] != '/') { fprintf(stderr, "Ignoring resource file '%s'='%s' as no absolute path!\n", -- 1.5.6.5