diff options
author | Adam Harrison <adamdharrison@gmail.com> | 2023-03-20 00:18:57 -0400 |
---|---|---|
committer | Adam Harrison <adamdharrison@gmail.com> | 2023-03-20 00:18:57 -0400 |
commit | 1ff0fed4c0dc8d056a0f8da712fe0a518a1eb729 (patch) | |
tree | 8639ac9a57418cafabd9947d4211017188e1199d | |
parent | dca7c64c2f339aa2c522c0c7687a85fd2b0e08b0 (diff) | |
download | lite-xl-plugin-manager-1ff0fed4c0dc8d056a0f8da712fe0a518a1eb729.tar.gz lite-xl-plugin-manager-1ff0fed4c0dc8d056a0f8da712fe0a518a1eb729.zip |
Modified fopen calls to use _wfopen where appropriate to improve UTF-8 support on windows.
-rw-r--r-- | src/lpm.c | 140 |
1 files changed, 87 insertions, 53 deletions
@@ -44,6 +44,57 @@ #include <Security/Security.h> #endif + +#if _WIN32 +static LPCWSTR lua_toutf16(lua_State* L, const char* str) { + if (str && str[0] == 0) + return L""; + int len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); + if (len > 0) { + LPWSTR output = (LPWSTR) malloc(sizeof(WCHAR) * len); + if (output) { + len = MultiByteToWideChar(CP_UTF8, 0, str, -1, output, len); + if (len > 0) { + lua_pushlstring(L, (char*)output, len * 2); + free(output); + return (LPCWSTR)lua_tostring(L, -1); + } + free(output); + } + } + luaL_error(L, "can't convert utf8 string"); + return NULL; +} + +static const char* lua_toutf8(lua_State* L, LPCWSTR str) { + int len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); + if (len > 0) { + char* output = (char *) malloc(sizeof(char) * len); + if (output) { + len = WideCharToMultiByte(CP_UTF8, 0, str, -1, output, len, NULL, NULL); + if (len) { + lua_pushlstring(L, output, len); + free(output); + return lua_tostring(L, -1); + } + free(output); + } + } + luaL_error(L, "can't convert utf16 string"); + return NULL; +} +#endif + +static FILE* lua_fopen(lua_State* L, const char* path, const char* mode) { + #ifdef _WIN32 + FILE* file = _wfopen(lua_toutf16(L, path), lua_toutf16(L, mode)); + lua_pop(L, 2); + return file; + #else + return fopen(path, mode); + #endif +} + static char hex_digits[] = "0123456789abcdef"; static int lpm_hash(lua_State* L) { size_t len; @@ -55,7 +106,7 @@ static int lpm_hash(lua_State* L) { mbedtls_sha256_init(&hash_ctx); mbedtls_sha256_starts_ret(&hash_ctx, 0); if (strcmp(type, "file") == 0) { - FILE* file = fopen(data, "rb"); + FILE* file = lua_fopen(L, data, "rb"); if (!file) { mbedtls_sha256_free(&hash_ctx); return luaL_error(L, "can't open %s", data); @@ -82,6 +133,7 @@ static int lpm_hash(lua_State* L) { return 1; } + int lpm_symlink(lua_State* L) { #ifndef _WIN32 if (symlink(luaL_checkstring(L, 1), luaL_checkstring(L, 2))) @@ -93,51 +145,15 @@ int lpm_symlink(lua_State* L) { } int lpm_chmod(lua_State* L) { - if (chmod(luaL_checkstring(L, 1), luaL_checkinteger(L, 2))) - return luaL_error(L, "can't chmod %s: %s", luaL_checkstring(L, 1), strerror(errno)); + #ifdef _WIN32 + if (_wchmod(lua_toutf16(L, luaL_checkstring(L, 1)), luaL_checkinteger(L, 2))) + #else + if (chmod(luaL_checkstring(L, 1), luaL_checkinteger(L, 2))) + #endif + return luaL_error(L, "can't chmod %s: %s", luaL_checkstring(L, 1), strerror(errno)); return 0; } -#if _WIN32 -static LPCWSTR lua_toutf16(lua_State* L, const char* str) { - if (str && str[0] == 0) - return L""; - int len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); - if (len > 0) { - LPWSTR output = (LPWSTR) malloc(sizeof(WCHAR) * len); - if (output) { - len = MultiByteToWideChar(CP_UTF8, 0, str, -1, output, len); - if (len > 0) { - lua_pushlstring(L, (char*)output, len * 2); - free(output); - return (LPCWSTR)lua_tostring(L, -1); - } - free(output); - } - } - luaL_error(L, "can't convert utf8 string"); - return NULL; -} - -static const char* lua_toutf8(lua_State* L, LPCWSTR str) { - int len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL); - if (len > 0) { - char* output = (char *) malloc(sizeof(char) * len); - if (output) { - len = WideCharToMultiByte(CP_UTF8, 0, str, -1, output, len, NULL, NULL); - if (len) { - lua_pushlstring(L, output, len); - free(output); - return lua_tostring(L, -1); - } - free(output); - } - } - luaL_error(L, "can't convert utf16 string"); - return NULL; -} -#endif - static int lpm_ls(lua_State *L) { const char *path = luaL_checkstring(L, 1); @@ -517,7 +533,7 @@ static int lpm_certs(lua_State* L) { } else { if (strcmp(type, "system") == 0) { #if _WIN32 - FILE* file = fopen(path, "wb"); + FILE* file = lua_fopen(L, path, "wb"); if (!file) return luaL_error(L, "can't open cert store %s for writing: %s", path, strerror(errno)); HCERTSTORE hSystemStore = CertOpenSystemStore(0, TEXT("ROOT")); @@ -615,7 +631,7 @@ static int lpm_extract(lua_State* L) { return luaL_error(L, "can't extract zip archive file %s, can't create directory %s: %s", src, target, strerror(errno)); } if (target[target_length-1] != '/') { - FILE* file = fopen(target, "wb"); + FILE* file = lua_fopen(L, target, "wb"); if (!file) { zip_fclose(zip_file); zip_close(archive); @@ -673,7 +689,11 @@ static int lpm_extract(lua_State* L) { int len = strlen(src) - 3; strncpy(actual_src, src, len < PATH_MAX ? len : PATH_MAX); actual_src[len] = 0; - FILE* file = fopen(actual_src, "wb"); + FILE* file = lua_fopen(L, actual_src, "wb"); + if (!file) { + gzclose(gzfile); + return luaL_error(L, "can't open %s for writing: %s", actual_src, strerror(errno)); + } while (1) { int length = gzread(gzfile, buffer, sizeof(buffer)); if (length == 0) @@ -889,7 +909,10 @@ static int lpm_get(lua_State* L) { int total_downloaded = body_length; int remaining = content_length - body_length; if (path) { - FILE* file = fopen(path, "wb"); + FILE* file = lua_fopen(L, path, "wb"); + if (!file) { + snprintf(err, sizeof(err), "can't open file %s: %s", path, strerror(errno)); goto cleanup; + } fwrite(header_end, sizeof(char), body_length, file); while (content_length == -1 || remaining > 0) { int length = lpm_socket_read(s, buffer, sizeof(buffer), ssl_ctx); @@ -952,16 +975,27 @@ static int lpm_get(lua_State* L) { } static int lpm_chdir(lua_State* L) { - if (chdir(luaL_checkstring(L, 1))) - return luaL_error(L, "error chdiring: %s", strerror(errno)); + #ifdef _WIN32 + if (_wchdir(lua_toutf16(L, luaL_checkstring(L, 1)))) + #else + if (chdir(luaL_checkstring(L, 1))) + #endif + return luaL_error(L, "error chdiring: %s", strerror(errno)); return 0; } static int lpm_pwd(lua_State* L) { - char buffer[MAX_PATH]; - if (!getcwd(buffer, sizeof(buffer))) - return luaL_error(L, "error getcwd: %s", strerror(errno)); - lua_pushstring(L, buffer); + #ifdef _WIN32 + wchar_t buffer[MAX_PATH]; + if (!_wgetcwd(buffer, sizeof(buffer))) + return luaL_error(L, "error getcwd: %s", strerror(errno)); + lua_toutf8(L, buffer); + #else + char buffer[MAX_PATH]; + if (!getcwd(buffer, sizeof(buffer))) + return luaL_error(L, "error getcwd: %s", strerror(errno)); + lua_pushstring(L, buffer); + #endif return 1; } |