aboutsummaryrefslogtreecommitdiff
path: root/src/lpm.c
diff options
context:
space:
mode:
authorAdam Harrison <adamdharrison@gmail.com>2023-03-20 00:18:57 -0400
committerAdam Harrison <adamdharrison@gmail.com>2023-03-20 00:18:57 -0400
commit1ff0fed4c0dc8d056a0f8da712fe0a518a1eb729 (patch)
tree8639ac9a57418cafabd9947d4211017188e1199d /src/lpm.c
parentdca7c64c2f339aa2c522c0c7687a85fd2b0e08b0 (diff)
downloadlite-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.
Diffstat (limited to 'src/lpm.c')
-rw-r--r--src/lpm.c140
1 files changed, 87 insertions, 53 deletions
diff --git a/src/lpm.c b/src/lpm.c
index 514549c..48644e4 100644
--- a/src/lpm.c
+++ b/src/lpm.c
@@ -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;
}