@@ -1158,7 +1158,7 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
1158
1158
offset ,
1159
1159
nread );
1160
1160
1161
- if (uvwasi == NULL || iovs == NULL || nread == NULL )
1161
+ if (uvwasi == NULL || ( iovs == NULL && iovs_len > 0 ) || nread == NULL || offset > INT64_MAX )
1162
1162
return UVWASI_EINVAL ;
1163
1163
1164
1164
err = uvwasi_fd_table_get (uvwasi -> fds ,
@@ -1169,6 +1169,14 @@ uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
1169
1169
if (err != UVWASI_ESUCCESS )
1170
1170
return err ;
1171
1171
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
+
1172
1180
err = uvwasi__setup_iovs (uvwasi , & bufs , iovs , iovs_len );
1173
1181
if (err != UVWASI_ESUCCESS ) {
1174
1182
uv_mutex_unlock (& wrap -> mutex );
@@ -1282,7 +1290,7 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
1282
1290
offset ,
1283
1291
nwritten );
1284
1292
1285
- if (uvwasi == NULL || iovs == NULL || nwritten == NULL )
1293
+ if (uvwasi == NULL || ( iovs == NULL && iovs_len > 0 ) || nwritten == NULL || offset > INT64_MAX )
1286
1294
return UVWASI_EINVAL ;
1287
1295
1288
1296
err = uvwasi_fd_table_get (uvwasi -> fds ,
@@ -1293,6 +1301,14 @@ uvwasi_errno_t uvwasi_fd_pwrite(uvwasi_t* uvwasi,
1293
1301
if (err != UVWASI_ESUCCESS )
1294
1302
return err ;
1295
1303
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
+
1296
1312
err = uvwasi__setup_ciovs (uvwasi , & bufs , iovs , iovs_len );
1297
1313
if (err != UVWASI_ESUCCESS ) {
1298
1314
uv_mutex_unlock (& wrap -> mutex );
@@ -1332,14 +1348,21 @@ uvwasi_errno_t uvwasi_fd_read(uvwasi_t* uvwasi,
1332
1348
iovs ,
1333
1349
iovs_len ,
1334
1350
nread );
1335
-
1336
- if (uvwasi == NULL || iovs == NULL || nread == NULL )
1351
+ if (uvwasi == NULL || (iovs == NULL && iovs_len > 0 ) || nread == NULL )
1337
1352
return UVWASI_EINVAL ;
1338
1353
1339
1354
err = uvwasi_fd_table_get (uvwasi -> fds , fd , & wrap , UVWASI_RIGHT_FD_READ , 0 );
1340
1355
if (err != UVWASI_ESUCCESS )
1341
1356
return err ;
1342
1357
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
+
1343
1366
err = uvwasi__setup_iovs (uvwasi , & bufs , iovs , iovs_len );
1344
1367
if (err != UVWASI_ESUCCESS ) {
1345
1368
uv_mutex_unlock (& wrap -> mutex );
@@ -1634,13 +1657,21 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
1634
1657
iovs_len ,
1635
1658
nwritten );
1636
1659
1637
- if (uvwasi == NULL || iovs == NULL || nwritten == NULL )
1660
+ if (uvwasi == NULL || ( iovs == NULL && iovs_len > 0 ) || nwritten == NULL )
1638
1661
return UVWASI_EINVAL ;
1639
1662
1640
1663
err = uvwasi_fd_table_get (uvwasi -> fds , fd , & wrap , UVWASI_RIGHT_FD_WRITE , 0 );
1641
1664
if (err != UVWASI_ESUCCESS )
1642
1665
return err ;
1643
1666
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
+
1644
1675
err = uvwasi__setup_ciovs (uvwasi , & bufs , iovs , iovs_len );
1645
1676
if (err != UVWASI_ESUCCESS ) {
1646
1677
uv_mutex_unlock (& wrap -> mutex );
@@ -2168,7 +2199,7 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
2168
2199
2169
2200
memcpy (buf , req .ptr , len );
2170
2201
buf [len ] = '\0' ;
2171
- * bufused = len + 1 ;
2202
+ * bufused = len ;
2172
2203
uv_fs_req_cleanup (& req );
2173
2204
return UVWASI_ESUCCESS ;
2174
2205
}
0 commit comments