@@ -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 | } |
|