Skip to content

Commit e30507b

Browse files
committed
Fix psql history on Windows for APPDATA with non-ascii characters
1 parent 439b251 commit e30507b

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

src/port/path.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,31 @@ get_man_path(const char *my_exec_path, char *ret_path)
796796
make_relative_path(ret_path, MANDIR, PGBINDIR, my_exec_path);
797797
}
798798

799+
#ifdef WIN32
800+
/*
801+
* make_wc_name
802+
*/
803+
804+
const wchar_t* make_wc_name(const char* name) {
805+
int wlen;
806+
size_t size = (size_t)strlen(name) + 1;
807+
size_t wsize = size * sizeof(wchar_t);
808+
wchar_t *p = (wchar_t*)malloc(wsize);
809+
wlen = MultiByteToWideChar(CP_ACP,0,(LPCCH)name,(int)size,(LPWSTR)p,(int)wsize);
810+
return p;
811+
}
812+
813+
/*
814+
* make_utf8_path
815+
*/
816+
const char* make_utf8_path(const wchar_t* s) {
817+
int len;
818+
size_t size = (size_t)wcslen(s) + 1;
819+
char *p = (char*)malloc(size * 6);
820+
len = WideCharToMultiByte(CP_UTF8,0,s,size,p,size * sizeof(wchar_t),NULL,NULL);
821+
return p;
822+
}
823+
#endif
799824

800825
/*
801826
* get_home_path
@@ -817,19 +842,27 @@ get_home_path(char *ret_path)
817842
strlcpy(ret_path, pwd->pw_dir, MAXPGPATH);
818843
return true;
819844
#else
820-
char *tmppath;
821-
845+
wchar_t *tmppath;
846+
wchar_t *vname;
847+
const char *utf8_path;
848+
822849
/*
823850
* Note: We use getenv() here because the more modern SHGetFolderPath()
824851
* would force the backend to link with shell32.lib, which eats valuable
825852
* desktop heap. XXX This function is used only in psql, which already
826853
* brings in shell32 via libpq. Moving this function to its own file
827854
* would keep it out of the backend, freeing it from this concern.
828855
*/
829-
tmppath = getenv("APPDATA");
856+
857+
vname = make_wc_name("APPDATA");
858+
tmppath = _wgetenv(vname);
859+
free(vname);
860+
830861
if (!tmppath)
831862
return false;
832-
snprintf(ret_path, MAXPGPATH, "%s/postgresql", tmppath);
863+
utf8_path = make_utf8_path(tmppath);
864+
snprintf(ret_path, MAXPGPATH, "%s\\postgresql", utf8_path);
865+
free(utf8_path);
833866
return true;
834867
#endif
835868
}

0 commit comments

Comments
 (0)