@tybys/wasm-util 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -118,6 +118,7 @@ async function resolvePathAsync(fs, fileDescriptor, path, flags) {
118
118
  const encoder = /*#__PURE__*/ new TextEncoder();
119
119
  // eslint-disable-next-line spaced-comment
120
120
  const decoder = /*#__PURE__*/ new TextDecoder();
121
+ const INT64_MAX = (BigInt(1) << BigInt(63)) - BigInt(1);
121
122
  function readStdin() {
122
123
  const value = window.prompt();
123
124
  if (value === null)
@@ -125,6 +126,14 @@ function readStdin() {
125
126
  const buffer = new TextEncoder().encode(value + '\n');
126
127
  return buffer;
127
128
  }
129
+ function validateFstFlagsOrReturn(flags) {
130
+ return (Boolean((flags) & ~(WasiFstFlag.SET_ATIM | WasiFstFlag.SET_ATIM_NOW |
131
+ WasiFstFlag.SET_MTIM | WasiFstFlag.SET_MTIM_NOW)) ||
132
+ ((flags) & (WasiFstFlag.SET_ATIM | WasiFstFlag.SET_ATIM_NOW)) ===
133
+ (WasiFstFlag.SET_ATIM | WasiFstFlag.SET_ATIM_NOW) ||
134
+ ((flags) & (WasiFstFlag.SET_MTIM | WasiFstFlag.SET_MTIM_NOW)) ===
135
+ (WasiFstFlag.SET_MTIM | WasiFstFlag.SET_MTIM_NOW));
136
+ }
128
137
  export class WASI {
129
138
  constructor(args, env, fds, asyncFs, fs, asyncify) {
130
139
  this.args_get = syscallWrap(this, 'args_get', function (argv, argv_buf) {
@@ -285,7 +294,7 @@ export class WASI {
285
294
  const { view } = getMemory(this);
286
295
  // preopen type is dir(0)
287
296
  view.setUint32(prestat, 0, true);
288
- view.setUint32(prestat + 4, encoder.encode(fileDescriptor.path).length + 1, true);
297
+ view.setUint32(prestat + 4, encoder.encode(fileDescriptor.path).length, true);
289
298
  return WasiErrno.ESUCCESS;
290
299
  });
291
300
  this.fd_prestat_dir_name = syscallWrap(this, 'fd_prestat_dir_name', function (fd, path, path_len) {
@@ -298,7 +307,7 @@ export class WASI {
298
307
  const fileDescriptor = wasi.fds.get(fd, BigInt(0), BigInt(0));
299
308
  if (fileDescriptor.preopen !== 1)
300
309
  return WasiErrno.EBADF;
301
- const buffer = encoder.encode(fileDescriptor.path + '\0');
310
+ const buffer = encoder.encode(fileDescriptor.path);
302
311
  const size = buffer.length;
303
312
  if (size > path_len)
304
313
  return WasiErrno.ENOBUFS;
@@ -493,6 +502,9 @@ export class WASI {
493
502
  this.sock_shutdown = syscallWrap(this, 'sock_shutdown', function () {
494
503
  return WasiErrno.ENOTSUP;
495
504
  });
505
+ this.sock_accept = syscallWrap(this, 'sock_accept', function () {
506
+ return WasiErrno.ENOTSUP;
507
+ });
496
508
  _wasi.set(this, {
497
509
  fds,
498
510
  args,
@@ -608,11 +620,17 @@ export class WASI {
608
620
  return { fileDescriptor, atim, mtim };
609
621
  }
610
622
  defineImport('fd_filestat_set_times', function fd_filestat_set_times(fd, atim, mtim, flags) {
623
+ if (validateFstFlagsOrReturn(flags)) {
624
+ return WasiErrno.EINVAL;
625
+ }
611
626
  const { fileDescriptor, atim: atimRes, mtim: mtimRes } = fdFilestatGetTimes.call(this, fd, atim, mtim, flags);
612
627
  const fs = getFs(this);
613
628
  fs.futimesSync(fileDescriptor.fd, Number(atimRes), Number(mtimRes));
614
629
  return WasiErrno.ESUCCESS;
615
630
  }, async function fd_filestat_set_times(fd, atim, mtim, flags) {
631
+ if (validateFstFlagsOrReturn(flags)) {
632
+ return WasiErrno.EINVAL;
633
+ }
616
634
  const { fileDescriptor, atim: atimRes, mtim: mtimRes } = fdFilestatGetTimes.call(this, fd, atim, mtim, flags);
617
635
  const h = fileDescriptor.fd;
618
636
  await h.utimes(Number(atimRes), Number(mtimRes));
@@ -621,12 +639,16 @@ export class WASI {
621
639
  defineImport('fd_pread', function fd_pread(fd, iovs, iovslen, offset, size) {
622
640
  iovs = Number(iovs);
623
641
  size = Number(size);
624
- if (iovs === 0 || size === 0) {
642
+ if ((iovs === 0 && iovslen) || size === 0 || offset > INT64_MAX) {
625
643
  return WasiErrno.EINVAL;
626
644
  }
627
645
  const { HEAPU8, view } = getMemory(this);
628
646
  const wasi = _wasi.get(this);
629
647
  const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_READ | WasiRights.FD_SEEK, BigInt(0));
648
+ if (!iovslen) {
649
+ view.setUint32(size, 0, true);
650
+ return WasiErrno.ESUCCESS;
651
+ }
630
652
  let totalSize = 0;
631
653
  const ioVecs = Array.from({ length: Number(iovslen) }, (_, i) => {
632
654
  const offset = iovs + (i * 8);
@@ -636,7 +658,14 @@ export class WASI {
636
658
  return HEAPU8.subarray(buf, buf + bufLen);
637
659
  });
638
660
  let nread = 0;
639
- const buffer = new Uint8Array(totalSize);
661
+ const buffer = (() => {
662
+ try {
663
+ return new Uint8Array(new SharedArrayBuffer(totalSize));
664
+ }
665
+ catch (_) {
666
+ return new Uint8Array(totalSize);
667
+ }
668
+ })();
640
669
  buffer._isBuffer = true;
641
670
  const fs = getFs(this);
642
671
  const bytesRead = fs.readSync(fileDescriptor.fd, buffer, 0, buffer.length, Number(offset));
@@ -646,12 +675,16 @@ export class WASI {
646
675
  }, async function (fd, iovs, iovslen, offset, size) {
647
676
  iovs = Number(iovs);
648
677
  size = Number(size);
649
- if (iovs === 0 || size === 0) {
678
+ if ((iovs === 0 && iovslen) || size === 0 || offset > INT64_MAX) {
650
679
  return WasiErrno.EINVAL;
651
680
  }
652
681
  const { HEAPU8, view } = getMemory(this);
653
682
  const wasi = _wasi.get(this);
654
683
  const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_READ | WasiRights.FD_SEEK, BigInt(0));
684
+ if (!iovslen) {
685
+ view.setUint32(size, 0, true);
686
+ return WasiErrno.ESUCCESS;
687
+ }
655
688
  let totalSize = 0;
656
689
  const ioVecs = Array.from({ length: Number(iovslen) }, (_, i) => {
657
690
  const offset = iovs + (i * 8);
@@ -671,12 +704,16 @@ export class WASI {
671
704
  defineImport('fd_pwrite', function fd_pwrite(fd, iovs, iovslen, offset, size) {
672
705
  iovs = Number(iovs);
673
706
  size = Number(size);
674
- if (iovs === 0 || size === 0) {
707
+ if ((iovs === 0 && iovslen) || size === 0 || offset > INT64_MAX) {
675
708
  return WasiErrno.EINVAL;
676
709
  }
677
710
  const { HEAPU8, view } = getMemory(this);
678
711
  const wasi = _wasi.get(this);
679
712
  const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_WRITE | WasiRights.FD_SEEK, BigInt(0));
713
+ if (!iovslen) {
714
+ view.setUint32(size, 0, true);
715
+ return WasiErrno.ESUCCESS;
716
+ }
680
717
  const buffer = concatBuffer(Array.from({ length: Number(iovslen) }, (_, i) => {
681
718
  const offset = iovs + (i * 8);
682
719
  const buf = view.getInt32(offset, true);
@@ -690,12 +727,16 @@ export class WASI {
690
727
  }, async function fd_pwrite(fd, iovs, iovslen, offset, size) {
691
728
  iovs = Number(iovs);
692
729
  size = Number(size);
693
- if (iovs === 0 || size === 0) {
730
+ if ((iovs === 0 && iovslen) || size === 0 || offset > INT64_MAX) {
694
731
  return WasiErrno.EINVAL;
695
732
  }
696
733
  const { HEAPU8, view } = getMemory(this);
697
734
  const wasi = _wasi.get(this);
698
735
  const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_WRITE | WasiRights.FD_SEEK, BigInt(0));
736
+ if (!iovslen) {
737
+ view.setUint32(size, 0, true);
738
+ return WasiErrno.ESUCCESS;
739
+ }
699
740
  const buffer = concatBuffer(Array.from({ length: Number(iovslen) }, (_, i) => {
700
741
  const offset = iovs + (i * 8);
701
742
  const buf = view.getInt32(offset, true);
@@ -709,12 +750,16 @@ export class WASI {
709
750
  defineImport('fd_read', function fd_read(fd, iovs, iovslen, size) {
710
751
  iovs = Number(iovs);
711
752
  size = Number(size);
712
- if (iovs === 0 || size === 0) {
753
+ if ((iovs === 0 && iovslen) || size === 0) {
713
754
  return WasiErrno.EINVAL;
714
755
  }
715
756
  const { HEAPU8, view } = getMemory(this);
716
757
  const wasi = _wasi.get(this);
717
758
  const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_READ, BigInt(0));
759
+ if (!iovslen) {
760
+ view.setUint32(size, 0, true);
761
+ return WasiErrno.ESUCCESS;
762
+ }
718
763
  let totalSize = 0;
719
764
  const ioVecs = Array.from({ length: Number(iovslen) }, (_, i) => {
720
765
  const offset = iovs + (i * 8);
@@ -733,7 +778,14 @@ export class WASI {
733
778
  nread = buffer ? copyMemory(ioVecs, buffer) : 0;
734
779
  }
735
780
  else {
736
- buffer = new Uint8Array(totalSize);
781
+ buffer = (() => {
782
+ try {
783
+ return new Uint8Array(new SharedArrayBuffer(totalSize));
784
+ }
785
+ catch (_) {
786
+ return new Uint8Array(totalSize);
787
+ }
788
+ })();
737
789
  buffer._isBuffer = true;
738
790
  const fs = getFs(this);
739
791
  const bytesRead = fs.readSync(fileDescriptor.fd, buffer, 0, buffer.length, Number(fileDescriptor.pos));
@@ -745,12 +797,16 @@ export class WASI {
745
797
  }, async function fd_read(fd, iovs, iovslen, size) {
746
798
  iovs = Number(iovs);
747
799
  size = Number(size);
748
- if (iovs === 0 || size === 0) {
800
+ if ((iovs === 0 && iovslen) || size === 0) {
749
801
  return WasiErrno.EINVAL;
750
802
  }
751
803
  const { HEAPU8, view } = getMemory(this);
752
804
  const wasi = _wasi.get(this);
753
805
  const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_READ, BigInt(0));
806
+ if (!iovslen) {
807
+ view.setUint32(size, 0, true);
808
+ return WasiErrno.ESUCCESS;
809
+ }
754
810
  let totalSize = 0;
755
811
  const ioVecs = Array.from({ length: Number(iovslen) }, (_, i) => {
756
812
  const offset = iovs + (i * 8);
@@ -903,12 +959,16 @@ export class WASI {
903
959
  defineImport('fd_write', function fd_write(fd, iovs, iovslen, size) {
904
960
  iovs = Number(iovs);
905
961
  size = Number(size);
906
- if (iovs === 0 || size === 0) {
962
+ if ((iovs === 0 && iovslen) || size === 0) {
907
963
  return WasiErrno.EINVAL;
908
964
  }
909
965
  const { HEAPU8, view } = getMemory(this);
910
966
  const wasi = _wasi.get(this);
911
967
  const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_WRITE, BigInt(0));
968
+ if (!iovslen) {
969
+ view.setUint32(size, 0, true);
970
+ return WasiErrno.ESUCCESS;
971
+ }
912
972
  const buffer = concatBuffer(Array.from({ length: Number(iovslen) }, (_, i) => {
913
973
  const offset = iovs + (i * 8);
914
974
  const buf = view.getInt32(offset, true);
@@ -929,12 +989,16 @@ export class WASI {
929
989
  }, async function fd_write(fd, iovs, iovslen, size) {
930
990
  iovs = Number(iovs);
931
991
  size = Number(size);
932
- if (iovs === 0 || size === 0) {
992
+ if ((iovs === 0 && iovslen) || size === 0) {
933
993
  return WasiErrno.EINVAL;
934
994
  }
935
995
  const { HEAPU8, view } = getMemory(this);
936
996
  const wasi = _wasi.get(this);
937
997
  const fileDescriptor = wasi.fds.get(fd, WasiRights.FD_WRITE, BigInt(0));
998
+ if (!iovslen) {
999
+ view.setUint32(size, 0, true);
1000
+ return WasiErrno.ESUCCESS;
1001
+ }
938
1002
  const buffer = concatBuffer(Array.from({ length: Number(iovslen) }, (_, i) => {
939
1003
  const offset = iovs + (i * 8);
940
1004
  const buf = view.getInt32(offset, true);
@@ -1031,15 +1095,12 @@ export class WASI {
1031
1095
  path_len = Number(path_len);
1032
1096
  if (path === 0)
1033
1097
  return WasiErrno.EINVAL;
1034
- if ((fst_flags) & ~(WasiFstFlag.SET_ATIM |
1035
- WasiFstFlag.SET_ATIM_NOW |
1036
- WasiFstFlag.SET_MTIM |
1037
- WasiFstFlag.SET_MTIM_NOW)) {
1038
- return WasiErrno.EINVAL;
1039
- }
1040
1098
  const { HEAPU8 } = getMemory(this);
1041
1099
  const wasi = _wasi.get(this);
1042
1100
  const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_FILESTAT_SET_TIMES, BigInt(0));
1101
+ if (validateFstFlagsOrReturn(fst_flags)) {
1102
+ return WasiErrno.EINVAL;
1103
+ }
1043
1104
  const fs = getFs(this);
1044
1105
  const resolvedPath = resolvePathSync(fs, fileDescriptor, decoder.decode(unsharedSlice(HEAPU8, path, path + path_len)), flags);
1045
1106
  if ((fst_flags & WasiFstFlag.SET_ATIM_NOW) === WasiFstFlag.SET_ATIM_NOW) {
@@ -1055,15 +1116,12 @@ export class WASI {
1055
1116
  path_len = Number(path_len);
1056
1117
  if (path === 0)
1057
1118
  return WasiErrno.EINVAL;
1058
- if ((fst_flags) & ~(WasiFstFlag.SET_ATIM |
1059
- WasiFstFlag.SET_ATIM_NOW |
1060
- WasiFstFlag.SET_MTIM |
1061
- WasiFstFlag.SET_MTIM_NOW)) {
1062
- return WasiErrno.EINVAL;
1063
- }
1064
1119
  const { HEAPU8 } = getMemory(this);
1065
1120
  const wasi = _wasi.get(this);
1066
1121
  const fileDescriptor = wasi.fds.get(fd, WasiRights.PATH_FILESTAT_SET_TIMES, BigInt(0));
1122
+ if (validateFstFlagsOrReturn(fst_flags)) {
1123
+ return WasiErrno.EINVAL;
1124
+ }
1067
1125
  const fs = getFs(this);
1068
1126
  const resolvedPath = await resolvePathAsync(fs, fileDescriptor, decoder.decode(unsharedSlice(HEAPU8, path, path + path_len)), flags);
1069
1127
  if ((fst_flags & WasiFstFlag.SET_ATIM_NOW) === WasiFstFlag.SET_ATIM_NOW) {
@@ -1262,7 +1320,7 @@ export class WASI {
1262
1320
  return WasiErrno.ENOBUFS;
1263
1321
  HEAPU8.set(linkData.subarray(0, len), buf);
1264
1322
  HEAPU8[buf + len] = 0;
1265
- view.setUint32(bufused, len + 1, true);
1323
+ view.setUint32(bufused, len, true);
1266
1324
  return WasiErrno.ESUCCESS;
1267
1325
  }, async function path_readlink(fd, path, path_len, buf, buf_len, bufused) {
1268
1326
  path = Number(path);
@@ -1286,7 +1344,7 @@ export class WASI {
1286
1344
  return WasiErrno.ENOBUFS;
1287
1345
  HEAPU8.set(linkData.subarray(0, len), buf);
1288
1346
  HEAPU8[buf + len] = 0;
1289
- view.setUint32(bufused, len + 1, true);
1347
+ view.setUint32(bufused, len, true);
1290
1348
  return WasiErrno.ESUCCESS;
1291
1349
  }, ['i32', 'i32', 'i32', 'i32', 'i32', 'i32'], ['i32']);
1292
1350
  defineImport('path_remove_directory', function path_remove_directory(fd, path, path_len) {
@@ -28,7 +28,8 @@ export const RIGHTS_ALL = WasiRights.FD_DATASYNC |
28
28
  WasiRights.PATH_UNLINK_FILE |
29
29
  WasiRights.PATH_REMOVE_DIRECTORY |
30
30
  WasiRights.POLL_FD_READWRITE |
31
- WasiRights.SOCK_SHUTDOWN;
31
+ WasiRights.SOCK_SHUTDOWN |
32
+ WasiRights.SOCK_ACCEPT;
32
33
  export const BLOCK_DEVICE_BASE = RIGHTS_ALL;
33
34
  export const BLOCK_DEVICE_INHERITING = RIGHTS_ALL;
34
35
  export const CHARACTER_DEVICE_BASE = RIGHTS_ALL;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tybys/wasm-util",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "WASI polyfill for browser and some wasm util",
5
5
  "main": "./lib/cjs/index.js",
6
6
  "module": "./dist/wasm-util.esm-bundler.js",