Skip to content

Commit 4c8fa3e

Browse files
mhdawsonrichardlau
authored andcommitted
deps: update uvwasi to 0.0.20 and fixup tests
- update uvwasi to 0.0.20 - adjust tests to reflect udpated behaviour from nodejs/uvwasi#224 included in uvwasi 0.0.20 Signed-off-by: Michael Dawson <[email protected]> PR-URL: #51355 Reviewed-By: Guy Bedford <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
1 parent 401837b commit 4c8fa3e

File tree

6 files changed

+153
-44
lines changed

6 files changed

+153
-44
lines changed

deps/uvwasi/include/uvwasi.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extern "C" {
1111

1212
#define UVWASI_VERSION_MAJOR 0
1313
#define UVWASI_VERSION_MINOR 0
14-
#define UVWASI_VERSION_PATCH 19
14+
#define UVWASI_VERSION_PATCH 20
1515
#define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \
1616
(UVWASI_VERSION_MINOR << 8) | \
1717
(UVWASI_VERSION_PATCH))

deps/uvwasi/src/path_resolver.c

+94-24
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,42 @@ static char* uvwasi__strchr_slash(const char* s) {
3131
return NULL;
3232
}
3333

34+
static uvwasi_errno_t uvwasi__combine_paths(const uvwasi_t* uvwasi,
35+
const char* path1,
36+
uvwasi_size_t path1_len,
37+
const char* path2,
38+
uvwasi_size_t path2_len,
39+
char** combined_path,
40+
uvwasi_size_t* combined_len) {
41+
/* This function joins two paths with '/'. */
42+
uvwasi_errno_t err;
43+
char* combined;
44+
int combined_size;
45+
int r;
46+
47+
*combined_path = NULL;
48+
*combined_len = 0;
49+
50+
/* The max combined size is the path1 length + the path2 length
51+
+ 2 for a terminating NULL and a possible path separator. */
52+
combined_size = path1_len + path2_len + 2;
53+
combined = uvwasi__malloc(uvwasi, combined_size);
54+
if (combined == NULL) return UVWASI_ENOMEM;
55+
56+
r = snprintf(combined, combined_size, "%s/%s", path1, path2);
57+
if (r <= 0) {
58+
err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
59+
goto exit;
60+
}
61+
62+
err = UVWASI_ESUCCESS;
63+
*combined_path = combined;
64+
*combined_len = strlen(combined);
65+
66+
exit:
67+
if (err != UVWASI_ESUCCESS) uvwasi__free(uvwasi, combined);
68+
return err;
69+
}
3470

3571
uvwasi_errno_t uvwasi__normalize_path(const char* path,
3672
uvwasi_size_t path_len,
@@ -234,39 +270,35 @@ static uvwasi_errno_t uvwasi__normalize_relative_path(
234270
uvwasi_errno_t err;
235271
char* combined;
236272
char* normalized;
237-
int combined_size;
238-
int fd_path_len;
239-
int norm_len;
240-
int r;
273+
uvwasi_size_t combined_len;
274+
uvwasi_size_t fd_path_len;
275+
uvwasi_size_t norm_len;
241276

242277
*normalized_path = NULL;
243278
*normalized_len = 0;
244279

245-
/* The max combined size is the path length + the file descriptor's path
246-
length + 2 for a terminating NULL and a possible path separator. */
247280
fd_path_len = strlen(fd->normalized_path);
248-
combined_size = path_len + fd_path_len + 2;
249-
combined = uvwasi__malloc(uvwasi, combined_size);
250-
if (combined == NULL)
251-
return UVWASI_ENOMEM;
252281

253-
normalized = uvwasi__malloc(uvwasi, combined_size);
282+
err = uvwasi__combine_paths(uvwasi,
283+
fd->normalized_path,
284+
fd_path_len,
285+
path,
286+
path_len,
287+
&combined,
288+
&combined_len);
289+
if (err != UVWASI_ESUCCESS) goto exit;
290+
291+
normalized = uvwasi__malloc(uvwasi, combined_len + 1);
254292
if (normalized == NULL) {
255293
err = UVWASI_ENOMEM;
256294
goto exit;
257295
}
258296

259-
r = snprintf(combined, combined_size, "%s/%s", fd->normalized_path, path);
260-
if (r <= 0) {
261-
err = uvwasi__translate_uv_error(uv_translate_sys_error(errno));
262-
goto exit;
263-
}
264-
265297
/* Normalize the input path. */
266298
err = uvwasi__normalize_path(combined,
267-
combined_size - 1,
299+
combined_len,
268300
normalized,
269-
combined_size - 1);
301+
combined_len);
270302
if (err != UVWASI_ESUCCESS)
271303
goto exit;
272304

@@ -374,9 +406,14 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
374406
char* host_path;
375407
char* normalized_path;
376408
char* link_target;
409+
char* normalized_parent;
410+
char* resolved_link_target;
377411
uvwasi_size_t input_len;
378412
uvwasi_size_t host_path_len;
379413
uvwasi_size_t normalized_len;
414+
uvwasi_size_t link_target_len;
415+
uvwasi_size_t normalized_parent_len;
416+
uvwasi_size_t resolved_link_target_len;
380417
int follow_count;
381418
int r;
382419

@@ -385,6 +422,8 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
385422
link_target = NULL;
386423
follow_count = 0;
387424
host_path = NULL;
425+
normalized_parent = NULL;
426+
resolved_link_target = NULL;
388427

389428
start:
390429
normalized_path = NULL;
@@ -458,19 +497,47 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
458497
goto exit;
459498
}
460499

461-
input_len = strlen(req.ptr);
500+
link_target_len = strlen(req.ptr);
462501
uvwasi__free(uvwasi, link_target);
463-
link_target = uvwasi__malloc(uvwasi, input_len + 1);
502+
link_target = uvwasi__malloc(uvwasi, link_target_len + 1);
464503
if (link_target == NULL) {
465504
uv_fs_req_cleanup(&req);
466505
err = UVWASI_ENOMEM;
467506
goto exit;
468507
}
469508

470-
memcpy(link_target, req.ptr, input_len + 1);
471-
input = link_target;
472-
uvwasi__free(uvwasi, normalized_path);
509+
memcpy(link_target, req.ptr, link_target_len + 1);
473510
uv_fs_req_cleanup(&req);
511+
512+
if (1 == uvwasi__is_absolute_path(link_target, link_target_len)) {
513+
input = link_target;
514+
input_len = link_target_len;
515+
} else {
516+
uvwasi__free(uvwasi, normalized_parent);
517+
uvwasi__free(uvwasi, resolved_link_target);
518+
519+
err = uvwasi__combine_paths(uvwasi,
520+
normalized_path,
521+
normalized_len,
522+
"..",
523+
2,
524+
&normalized_parent,
525+
&normalized_parent_len);
526+
if (err != UVWASI_ESUCCESS) goto exit;
527+
err = uvwasi__combine_paths(uvwasi,
528+
normalized_parent,
529+
normalized_parent_len,
530+
link_target,
531+
link_target_len,
532+
&resolved_link_target,
533+
&resolved_link_target_len);
534+
if (err != UVWASI_ESUCCESS) goto exit;
535+
536+
input = resolved_link_target;
537+
input_len = resolved_link_target_len;
538+
}
539+
540+
uvwasi__free(uvwasi, normalized_path);
474541
goto start;
475542
}
476543

@@ -484,5 +551,8 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
484551

485552
uvwasi__free(uvwasi, link_target);
486553
uvwasi__free(uvwasi, normalized_path);
554+
uvwasi__free(uvwasi, normalized_parent);
555+
uvwasi__free(uvwasi, resolved_link_target);
556+
487557
return err;
488558
}

deps/uvwasi/src/uvwasi.c

+45-10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
# include <dirent.h>
99
# include <time.h>
1010
#else
11+
# define _CRT_INTERNAL_NONSTDC_NAMES 1
12+
# include <sys/stat.h>
1113
# include <io.h>
1214
#endif /* _WIN32 */
1315

@@ -17,6 +19,10 @@
1719
# define UVWASI_FD_READDIR_SUPPORTED 1
1820
#endif
1921

22+
#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
23+
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
24+
#endif
25+
2026
#include "uvwasi.h"
2127
#include "uvwasi_alloc.h"
2228
#include "uv.h"
@@ -37,10 +43,13 @@
3743

3844
#define VALIDATE_FSTFLAGS_OR_RETURN(flags) \
3945
do { \
40-
if ((flags) & ~(UVWASI_FILESTAT_SET_ATIM | \
41-
UVWASI_FILESTAT_SET_ATIM_NOW | \
42-
UVWASI_FILESTAT_SET_MTIM | \
43-
UVWASI_FILESTAT_SET_MTIM_NOW)) { \
46+
uvwasi_fstflags_t f = flags; \
47+
if (((f) & ~(UVWASI_FILESTAT_SET_ATIM | UVWASI_FILESTAT_SET_ATIM_NOW | \
48+
UVWASI_FILESTAT_SET_MTIM | UVWASI_FILESTAT_SET_MTIM_NOW)) || \
49+
((f) & (UVWASI_FILESTAT_SET_ATIM | UVWASI_FILESTAT_SET_ATIM_NOW)) \
50+
== (UVWASI_FILESTAT_SET_ATIM | UVWASI_FILESTAT_SET_ATIM_NOW) || \
51+
((f) & (UVWASI_FILESTAT_SET_MTIM | UVWASI_FILESTAT_SET_MTIM_NOW)) \
52+
== (UVWASI_FILESTAT_SET_MTIM | UVWASI_FILESTAT_SET_MTIM_NOW)) { \
4453
return UVWASI_EINVAL; \
4554
} \
4655
} while (0)
@@ -624,9 +633,10 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
624633
uvwasi_advice_t advice) {
625634
struct uvwasi_fd_wrap_t* wrap;
626635
uvwasi_errno_t err;
636+
uv_fs_t req;
637+
int r;
627638
#ifdef POSIX_FADV_NORMAL
628639
int mapped_advice;
629-
int r;
630640
#endif /* POSIX_FADV_NORMAL */
631641

632642
UVWASI_DEBUG("uvwasi_fd_advise(uvwasi=%p, fd=%d, offset=%"PRIu64", "
@@ -679,14 +689,27 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi,
679689
if (err != UVWASI_ESUCCESS)
680690
return err;
681691

692+
r = uv_fs_fstat(NULL, &req, wrap->fd, NULL);
693+
if (r == -1) {
694+
err = uvwasi__translate_uv_error(r);
695+
goto exit;
696+
}
697+
698+
if (S_ISDIR(req.statbuf.st_mode)) {
699+
err = UVWASI_EBADF;
700+
goto exit;
701+
}
702+
682703
err = UVWASI_ESUCCESS;
683704

684705
#ifdef POSIX_FADV_NORMAL
685706
r = posix_fadvise(wrap->fd, offset, len, mapped_advice);
686707
if (r != 0)
687708
err = uvwasi__translate_uv_error(uv_translate_sys_error(r));
688709
#endif /* POSIX_FADV_NORMAL */
710+
exit:
689711
uv_mutex_unlock(&wrap->mutex);
712+
uv_fs_req_cleanup(&req);
690713
return err;
691714
}
692715

@@ -1775,8 +1798,6 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
17751798
if (uvwasi == NULL || path == NULL)
17761799
return UVWASI_EINVAL;
17771800

1778-
VALIDATE_FSTFLAGS_OR_RETURN(fst_flags);
1779-
17801801
err = uvwasi_fd_table_get(uvwasi->fds,
17811802
fd,
17821803
&wrap,
@@ -1785,6 +1806,8 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
17851806
if (err != UVWASI_ESUCCESS)
17861807
return err;
17871808

1809+
VALIDATE_FSTFLAGS_OR_RETURN(fst_flags);
1810+
17881811
err = uvwasi__resolve_path(uvwasi,
17891812
wrap,
17901813
path,
@@ -2306,6 +2329,7 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
23062329
uvwasi_fd_t fd,
23072330
const char* new_path,
23082331
uvwasi_size_t new_path_len) {
2332+
char* truncated_old_path;
23092333
char* resolved_new_path;
23102334
struct uvwasi_fd_wrap_t* wrap;
23112335
uvwasi_errno_t err;
@@ -2332,6 +2356,15 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
23322356
if (err != UVWASI_ESUCCESS)
23332357
return err;
23342358

2359+
truncated_old_path = uvwasi__malloc(uvwasi, old_path_len + 1);
2360+
if (truncated_old_path == NULL) {
2361+
uv_mutex_unlock(&wrap->mutex);
2362+
return UVWASI_ENOMEM;
2363+
}
2364+
2365+
memcpy(truncated_old_path, old_path, old_path_len);
2366+
truncated_old_path[old_path_len] = '\0';
2367+
23352368
err = uvwasi__resolve_path(uvwasi,
23362369
wrap,
23372370
new_path,
@@ -2340,12 +2373,14 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
23402373
0);
23412374
if (err != UVWASI_ESUCCESS) {
23422375
uv_mutex_unlock(&wrap->mutex);
2376+
uvwasi__free(uvwasi, truncated_old_path);
23432377
return err;
23442378
}
23452379

23462380
/* Windows support may require setting the flags option. */
2347-
r = uv_fs_symlink(NULL, &req, old_path, resolved_new_path, 0, NULL);
2381+
r = uv_fs_symlink(NULL, &req, truncated_old_path, resolved_new_path, 0, NULL);
23482382
uv_mutex_unlock(&wrap->mutex);
2383+
uvwasi__free(uvwasi, truncated_old_path);
23492384
uvwasi__free(uvwasi, resolved_new_path);
23502385
uv_fs_req_cleanup(&req);
23512386
if (r != 0)
@@ -2696,7 +2731,7 @@ uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi,
26962731
uvwasi_sdflags_t how) {
26972732
struct uvwasi_fd_wrap_t* wrap;
26982733
uvwasi_errno_t err = 0;
2699-
shutdown_data_t shutdown_data;
2734+
shutdown_data_t shutdown_data = {0};
27002735

27012736
if (how & ~UVWASI_SHUT_WR)
27022737
return UVWASI_ENOTSUP;
@@ -2794,7 +2829,7 @@ uvwasi_errno_t uvwasi_sock_accept(uvwasi_t* uvwasi,
27942829
goto close_sock_and_error_exit;
27952830
}
27962831

2797-
int r = uv_accept((uv_stream_t*) wrap->sock, (uv_stream_t*) uv_connect_sock);
2832+
r = uv_accept((uv_stream_t*) wrap->sock, (uv_stream_t*) uv_connect_sock);
27982833
if (r == UV_EAGAIN) {
27992834
// still no connection or error so run the loop again
28002835
continue;

test/wasi/c/create_symlink.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <unistd.h>
55

66
int main() {
7-
const char* target = "./input.txt";
7+
const char* target = "./input-in-subdir.txt";
88
const char* linkpath = "/sandbox/subdir/test_link";
99
char readlink_result[128];
1010
size_t result_size = sizeof(readlink_result);

test/wasi/test-wasi-symlinks.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ if (process.argv[2] === 'wasi-child') {
4242
const sandboxedFile = path.join(sandbox, 'input.txt');
4343
const externalFile = tmpdir.resolve('outside.txt');
4444
const sandboxedDir = path.join(sandbox, 'subdir');
45+
const sandboxedFileInSubdir = path.join(sandboxedDir, 'input-in-subdir.txt');
4546
const sandboxedSymlink = path.join(sandboxedDir, 'input_link.txt');
4647
const escapingSymlink = path.join(sandboxedDir, 'outside.txt');
4748
const loopSymlink1 = path.join(sandboxedDir, 'loop1');
@@ -52,13 +53,14 @@ if (process.argv[2] === 'wasi-child') {
5253
fs.mkdirSync(sandboxedDir);
5354
fs.mkdirSync(sandboxedTmp);
5455
fs.writeFileSync(sandboxedFile, 'hello from input.txt', 'utf8');
56+
fs.writeFileSync(sandboxedFileInSubdir, 'hello from input in subdir.txt',
57+
'utf8');
5558
fs.writeFileSync(externalFile, 'this should be inaccessible', 'utf8');
56-
fs.symlinkSync(path.join('.', 'input.txt'), sandboxedSymlink, 'file');
57-
fs.symlinkSync(path.join('..', 'outside.txt'), escapingSymlink, 'file');
58-
fs.symlinkSync(path.join('subdir', 'loop2'),
59-
loopSymlink1, 'file');
60-
fs.symlinkSync(path.join('subdir', 'loop1'),
61-
loopSymlink2, 'file');
59+
fs.symlinkSync(path.join('.', 'input-in-subdir.txt'),
60+
sandboxedSymlink, 'file');
61+
fs.symlinkSync(path.join('..', '..', 'outside.txt'), escapingSymlink, 'file');
62+
fs.symlinkSync('loop2', loopSymlink1, 'file');
63+
fs.symlinkSync('loop1', loopSymlink2, 'file');
6264

6365
function runWASI(options) {
6466
console.log('executing', options.test);
@@ -76,8 +78,10 @@ if (process.argv[2] === 'wasi-child') {
7678
assert.strictEqual(child.stdout.toString(), options.stdout || '');
7779
}
7880

79-
runWASI({ test: 'create_symlink', stdout: 'hello from input.txt' });
80-
runWASI({ test: 'follow_symlink', stdout: 'hello from input.txt' });
81+
runWASI({ test: 'create_symlink',
82+
stdout: 'hello from input in subdir.txt' });
83+
runWASI({ test: 'follow_symlink',
84+
stdout: 'hello from input in subdir.txt' });
8185
runWASI({ test: 'link' });
8286
runWASI({ test: 'symlink_escape' });
8387
runWASI({ test: 'symlink_loop' });

test/wasi/wasm/create_symlink.wasm

883 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)