| ... | @@ -237,7 +237,7 @@ int main(int argc, char **argv) { | ... | @@ -237,7 +237,7 @@ int main(int argc, char **argv) { |
| 237 | | 237 | |
| 238 | des[3].filetype = wasi_filetype_directory; | 238 | des[3].filetype = wasi_filetype_directory; |
| 239 | des[3].guest_path = dupe("/lib", sizeof("/lib")); | 239 | des[3].guest_path = dupe("/lib", sizeof("/lib")); |
| 240 | des[3].host_path = dupe(argv[1], strlen(argv[1])); | 240 | des[3].host_path = dupe(argv[1], strlen(argv[1]) + 1); |
| 241 | | 241 | |
| 242 | fd_len = 6; | 242 | fd_len = 6; |
| 243 | fds = calloc(sizeof(struct FileDescriptor), fd_len); | 243 | fds = calloc(sizeof(struct FileDescriptor), fd_len); |
| ... | @@ -252,8 +252,27 @@ int main(int argc, char **argv) { | ... | @@ -252,8 +252,27 @@ int main(int argc, char **argv) { |
| 252 | wasm__start(); | 252 | wasm__start(); |
| 253 | } | 253 | } |
| 254 | | 254 | |
| | 255 | static bool isLetter(char c) { |
| | 256 | return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); |
| | 257 | } |
| | 258 | static bool isPathSep(char c) { |
| | 259 | return c == '/' || c == '\\'; |
| | 260 | } |
| | 261 | static bool isAbsPath(const char *path, uint32_t path_len) { |
| | 262 | if (path_len >= 1 && isPathSep(path[0])) return true; |
| | 263 | if (path_len >= 3 && isLetter(path[0]) && path[1] == ':' && isPathSep(path[2])) return true; |
| | 264 | return false; |
| | 265 | } |
| | 266 | static bool isSamePath(const char *a, const char *b, uint32_t len) { |
| | 267 | for (uint32_t i = 0; i < len; i += 1) { |
| | 268 | if (isPathSep(a[i]) && isPathSep(b[i])) continue; |
| | 269 | if (a[i] != b[i]) return false; |
| | 270 | } |
| | 271 | return true; |
| | 272 | } |
| | 273 | |
| 255 | static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32_t path_len, enum wasi_filetype filetype, time_t tim, uint32_t *res_de) { | 274 | static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32_t path_len, enum wasi_filetype filetype, time_t tim, uint32_t *res_de) { |
| 256 | if (path[0] != '/') { | 275 | if (isAbsPath(path, path_len)) { |
| 257 | if (dir_fd >= fd_len || fds[dir_fd].de >= de_len) return wasi_errno_badf; | 276 | if (dir_fd >= fd_len || fds[dir_fd].de >= de_len) return wasi_errno_badf; |
| 258 | if (des[fds[dir_fd].de].filetype != wasi_filetype_directory) return wasi_errno_notdir; | 277 | if (des[fds[dir_fd].de].filetype != wasi_filetype_directory) return wasi_errno_notdir; |
| 259 | } | 278 | } |
| ... | @@ -267,7 +286,7 @@ static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32 | ... | @@ -267,7 +286,7 @@ static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32 |
| 267 | de->atim = tim; | 286 | de->atim = tim; |
| 268 | de->mtim = tim; | 287 | de->mtim = tim; |
| 269 | de->ctim = tim; | 288 | de->ctim = tim; |
| 270 | if (path[0] == '/') { | 289 | if (isAbsPath(path, path_len)) { |
| 271 | de->guest_path = malloc(path_len + 1); | 290 | de->guest_path = malloc(path_len + 1); |
| 272 | if (de->guest_path == NULL) return wasi_errno_nomem; | 291 | if (de->guest_path == NULL) return wasi_errno_nomem; |
| 273 | memcpy(&de->guest_path[0], path, path_len); | 292 | memcpy(&de->guest_path[0], path, path_len); |
| ... | @@ -307,10 +326,10 @@ static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32 | ... | @@ -307,10 +326,10 @@ static enum wasi_errno DirEntry_create(uint32_t dir_fd, const char *path, uint32 |
| 307 | | 326 | |
| 308 | static enum wasi_errno DirEntry_lookup(uint32_t dir_fd, uint32_t flags, const char *path, uint32_t path_len, uint32_t *res_de) { | 327 | static enum wasi_errno DirEntry_lookup(uint32_t dir_fd, uint32_t flags, const char *path, uint32_t path_len, uint32_t *res_de) { |
| 309 | (void)flags; | 328 | (void)flags; |
| 310 | if (path[0] == '/') { | 329 | if (isAbsPath(path, path_len)) { |
| 311 | for (uint32_t de = 0; de < de_len; de += 1) { | 330 | for (uint32_t de = 0; de < de_len; de += 1) { |
| 312 | if (des[de].guest_path == NULL) continue; | 331 | if (des[de].guest_path == NULL) continue; |
| 313 | if (memcmp(&des[de].guest_path[0], path, path_len) != 0) continue; | 332 | if (!isSamePath(&des[de].guest_path[0], path, path_len)) continue; |
| 314 | if (des[de].guest_path[path_len] != '\0') continue; | 333 | if (des[de].guest_path[path_len] != '\0') continue; |
| 315 | if (res_de != NULL) *res_de = de; | 334 | if (res_de != NULL) *res_de = de; |
| 316 | return wasi_errno_success; | 335 | return wasi_errno_success; |
| ... | @@ -323,9 +342,9 @@ static enum wasi_errno DirEntry_lookup(uint32_t dir_fd, uint32_t flags, const ch | ... | @@ -323,9 +342,9 @@ static enum wasi_errno DirEntry_lookup(uint32_t dir_fd, uint32_t flags, const ch |
| 323 | size_t dir_guest_path_len = strlen(dir_de->guest_path); | 342 | size_t dir_guest_path_len = strlen(dir_de->guest_path); |
| 324 | for (uint32_t de = 0; de < de_len; de += 1) { | 343 | for (uint32_t de = 0; de < de_len; de += 1) { |
| 325 | if (des[de].guest_path == NULL) continue; | 344 | if (des[de].guest_path == NULL) continue; |
| 326 | if (memcmp(&des[de].guest_path[0], dir_de->guest_path, dir_guest_path_len) != 0) continue; | 345 | if (!isSamePath(&des[de].guest_path[0], dir_de->guest_path, dir_guest_path_len)) continue; |
| 327 | if (des[de].guest_path[dir_guest_path_len] != '/') continue; | 346 | if (!isPathSep(des[de].guest_path[dir_guest_path_len])) continue; |
| 328 | if (memcmp(&des[de].guest_path[dir_guest_path_len + 1], path, path_len) != 0) continue; | 347 | if (!isSamePath(&des[de].guest_path[dir_guest_path_len + 1], path, path_len)) continue; |
| 329 | if (des[de].guest_path[dir_guest_path_len + 1 + path_len] != '\0') continue; | 348 | if (des[de].guest_path[dir_guest_path_len + 1 + path_len] != '\0') continue; |
| 330 | if (res_de != NULL) *res_de = de; | 349 | if (res_de != NULL) *res_de = de; |
| 331 | return wasi_errno_success; | 350 | return wasi_errno_success; |