@@ -1158,7 +1158,7 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
11581158 offset ,
11591159 nread );
11601160
1161- if (uvwasi == NULL || iovs == NULL || nread == NULL )
1161+ if (uvwasi == NULL || ( iovs == NULL && iovs_len > 0 ) || nread == NULL || offset > INT64_MAX )
11621162 return UVWASI_EINVAL ;
11631163
11641164 err = uvwasi_fd_table_get (uvwasi -> fds ,
@@ -1169,6 +1169,14 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
11691169 if (err != UVWASI_ESUCCESS )
11701170 return err ;
11711171
1172+ // libuv returns EINVAL in this case. To behave consistently with other
1173+ // Wasm runtimes, return OK here with a no-op.
1174+ if (iovs_len == 0 ) {
1175+ uv_mutex_unlock (& wrap -> mutex );
1176+ * nread = 0 ;
1177+ return UVWASI_ESUCCESS ;
1178+ }
1179+
11721180 err = uvwasi__setup_iovs (uvwasi , & bufs , iovs , iovs_len );
11731181 if (err != UVWASI_ESUCCESS ) {
11741182 uv_mutex_unlock (& wrap -> mutex );
@@ -1282,7 +1290,7 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
12821290 offset ,
12831291 nwritten );
12841292
1285- if (uvwasi == NULL || iovs == NULL || nwritten == NULL )
1293+ if (uvwasi == NULL || ( iovs == NULL && iovs_len > 0 ) || nwritten == NULL || offset > INT64_MAX )
12861294 return UVWASI_EINVAL ;
12871295
12881296 err = uvwasi_fd_table_get (uvwasi -> fds ,
@@ -1293,6 +1301,14 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
12931301 if (err != UVWASI_ESUCCESS )
12941302 return err ;
12951303
1304+ // libuv returns EINVAL in this case. To behave consistently with other
1305+ // Wasm runtimes, return OK here with a no-op.
1306+ if (iovs_len == 0 ) {
1307+ uv_mutex_unlock (& wrap -> mutex );
1308+ * nwritten = 0 ;
1309+ return UVWASI_ESUCCESS ;
1310+ }
1311+
12961312 err = uvwasi__setup_ciovs (uvwasi , & bufs , iovs , iovs_len );
12971313 if (err != UVWASI_ESUCCESS ) {
12981314 uv_mutex_unlock (& wrap -> mutex );
@@ -1332,14 +1348,21 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
13321348 iovs ,
13331349 iovs_len ,
13341350 nread );
1335-
1336- if (uvwasi == NULL || iovs == NULL || nread == NULL )
1351+ if (uvwasi == NULL || (iovs == NULL && iovs_len > 0 ) || nread == NULL )
13371352 return UVWASI_EINVAL ;
13381353
13391354 err = uvwasi_fd_table_get (uvwasi -> fds , fd , & wrap , UVWASI_RIGHT_FD_READ , 0 );
13401355 if (err != UVWASI_ESUCCESS )
13411356 return err ;
13421357
1358+ // libuv returns EINVAL in this case. To behave consistently with other
1359+ // Wasm runtimes, return OK here with a no-op.
1360+ if (iovs_len == 0 ) {
1361+ uv_mutex_unlock (& wrap -> mutex );
1362+ * nread = 0 ;
1363+ return UVWASI_ESUCCESS ;
1364+ }
1365+
13431366 err = uvwasi__setup_iovs (uvwasi , & bufs , iovs , iovs_len );
13441367 if (err != UVWASI_ESUCCESS ) {
13451368 uv_mutex_unlock (& wrap -> mutex );
@@ -1634,13 +1657,21 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
16341657 iovs_len ,
16351658 nwritten );
16361659
1637- if (uvwasi == NULL || iovs == NULL || nwritten == NULL )
1660+ if (uvwasi == NULL || ( iovs == NULL && iovs_len > 0 ) || nwritten == NULL )
16381661 return UVWASI_EINVAL ;
16391662
16401663 err = uvwasi_fd_table_get (uvwasi -> fds , fd , & wrap , UVWASI_RIGHT_FD_WRITE , 0 );
16411664 if (err != UVWASI_ESUCCESS )
16421665 return err ;
16431666
1667+ // libuv returns EINVAL in this case. To behave consistently with other
1668+ // Wasm runtimes, return OK here with a no-op.
1669+ if (iovs_len == 0 ) {
1670+ uv_mutex_unlock (& wrap -> mutex );
1671+ * nwritten = 0 ;
1672+ return UVWASI_ESUCCESS ;
1673+ }
1674+
16441675 err = uvwasi__setup_ciovs (uvwasi , & bufs , iovs , iovs_len );
16451676 if (err != UVWASI_ESUCCESS ) {
16461677 uv_mutex_unlock (& wrap -> mutex );
@@ -2168,7 +2199,7 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
21682199
21692200 memcpy (buf , req .ptr , len );
21702201 buf [len ] = '\0' ;
2171- * bufused = len + 1 ;
2202+ * bufused = len ;
21722203 uv_fs_req_cleanup (& req );
21732204 return UVWASI_ESUCCESS ;
21742205}
0 commit comments