json-as 1.0.0-beta.10 → 1.0.0-beta.11

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.
package/CHANGELOG CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## 2025-03-04 - 1.0.0-beta.11
4
+
5
+ - fix: wrongly assumed pointer types within arbitrary deserialization
6
+ - fix: wrong pointer type being passed during map deserialization
7
+
3
8
  ## 2025-03-04 - 1.0.0-beta.10
4
9
 
5
10
  - fix: transform not generating the right load operations for keys
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
7
7
  █████ ███████ ██████ ██ ████ ██ ██ ███████
8
8
  </span>
9
- AssemblyScript - v1.0.0-beta.10
9
+ AssemblyScript - v1.0.0-beta.11
10
10
  </pre>
11
11
  </h5>
12
12
 
@@ -31,7 +31,7 @@ JSON is the de-facto serialization format of modern web applications, but its se
31
31
  ## 💾 Installation
32
32
 
33
33
  ```bash
34
- npm install json-as@1.0.0-beta.10
34
+ npm install json-as@1.0.0-beta.11
35
35
  ```
36
36
 
37
37
  Add the `--transform` to your `asc` command (e.g. in package.json)
@@ -0,0 +1,7 @@
1
+ import { JSON } from "..";
2
+ import { describe, expect } from "./lib";
3
+
4
+ describe("Should deserialize complex objects", () => {
5
+ const input = '{"a":{"b":{"c":[{"d":"random value 1"},{"e":["value 2","value 3"]}],"f":{"g":{"h":[1,2,3],"i":{"j":"nested value"}}}},"k":"simple value"},"l":[{"m":"another value","n":{"o":"deep nested","p":[{"q":"even deeper"},"final value"]}}],"r":null}';
6
+ expect(JSON.stringify(JSON.parse<Map<string, JSON.Raw>>(input))).toBe(input);
7
+ })
@@ -4,14 +4,15 @@ import { deserializeBoolean } from "./bool";
4
4
  import { deserializeFloat } from "./float";
5
5
  import { deserializeString } from "./string";
6
6
  import { deserializeObject } from "./object";
7
+ import { BRACE_LEFT, BRACKET_LEFT, QUOTE } from "../../custom/chars";
7
8
 
8
9
  export function deserializeArbitrary(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value {
9
10
  const firstChar = load<u16>(srcStart);
10
- if (firstChar == 34) return JSON.Value.from(deserializeString(srcStart, srcEnd, dst));
11
- else if (firstChar == 123) return JSON.Value.from(deserializeObject(srcStart, srcEnd, dst));
11
+ if (firstChar == QUOTE) return JSON.Value.from(deserializeString(srcStart, srcEnd, 0));
12
+ else if (firstChar == BRACE_LEFT) return JSON.Value.from(deserializeObject(srcStart, srcEnd, 0));
12
13
  else if (firstChar - 48 <= 9 || firstChar == 45) return JSON.Value.from(deserializeFloat<f64>(srcStart, srcEnd));
13
- else if (firstChar == 91) {
14
- return JSON.Value.from(deserializeArray<JSON.Value[]>(srcStart, srcEnd, dst));
14
+ else if (firstChar == BRACKET_LEFT) {
15
+ return JSON.Value.from(deserializeArray<JSON.Value[]>(srcStart, srcEnd, 0));
15
16
  } else if (firstChar == 116 || firstChar == 102) return JSON.Value.from(deserializeBoolean(srcStart, srcEnd));
16
17
  return unreachable();
17
18
  }
@@ -1,5 +1,5 @@
1
1
  import { isSpace } from "../../../util";
2
- import { COMMA, BRACE_RIGHT, BRACKET_RIGHT } from "../../../custom/chars";
2
+ import { COMMA, BRACKET_RIGHT } from "../../../custom/chars";
3
3
  import { JSON } from "../../..";
4
4
 
5
5
  export function deserializeFloatArray<T extends number[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
@@ -4,7 +4,7 @@ import { isSpace } from "../../util";
4
4
  import { ptrToStr } from "../../util/ptrToStr";
5
5
 
6
6
  export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd: usize, dst: usize): T {
7
- const out = changetype<nonnull<T>>(dst || __new(offsetof<T>(), idof<T>()));
7
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
8
8
  // @ts-ignore: type
9
9
  if (!isString<indexof<T>>() && !isInteger<indexof<T>>() && !isFloat<indexof<T>>()) throw new Error("Map key must also be a valid JSON key!");
10
10
 
@@ -129,7 +129,7 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
129
129
  if (load<u64>(srcStart) == 28429475166421108) {
130
130
  // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
131
131
  // @ts-ignore: type
132
- out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 8)));
132
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 8)));
133
133
  // while (isSpace(load<u16>((srcStart += 2)))) {
134
134
  // /* empty */
135
135
  // }
@@ -141,7 +141,7 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
141
141
  if (load<u64>(srcStart, 2) == 28429466576093281) {
142
142
  // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
143
143
  // @ts-ignore: type
144
- out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 10)));
144
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 10)));
145
145
  // while (isSpace(load<u16>((srcStart += 2)))) {
146
146
  // /* empty */
147
147
  // }
@@ -153,7 +153,7 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
153
153
  if (load<u64>(srcStart) == 30399761348886638) {
154
154
  // console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
155
155
  // @ts-ignore: type
156
- out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 8)));
156
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 8)));
157
157
  // while (isSpace(load<u16>((srcStart += 2)))) {
158
158
  /* empty */
159
159
  // }
@@ -169,11 +169,4 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
169
169
  }
170
170
  }
171
171
  return out;
172
- }
173
-
174
- function sliceTo(srcStart: usize, srcEnd: usize): string {
175
- const dstSize = srcEnd - srcStart;
176
- const dst = __new(dstSize, idof<string>());
177
- memory.copy(dst, srcStart, dstSize);
178
- return changetype<string>(dst);
179
- }
172
+ }
@@ -1,11 +1,11 @@
1
1
  import { JSON } from "../..";
2
- import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T } from "../../custom/chars";
2
+ import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars";
3
3
  import { isSpace } from "../../util";
4
4
  import { ptrToStr } from "../../util/ptrToStr";
5
5
  import { deserializeArbitrary } from "./arbitrary";
6
6
 
7
7
  export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): JSON.Obj {
8
- const out = new JSON.Obj();
8
+ const out = changetype<JSON.Obj>(dst || changetype<usize>(new JSON.Obj()));
9
9
 
10
10
  let keyStart: usize = 0;
11
11
  let keyEnd: usize = 0;
@@ -14,7 +14,12 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
14
14
  let lastIndex: usize = 0;
15
15
 
16
16
  while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
17
- while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
17
+ while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2; // would like to optimize this later
18
+
19
+ if (srcStart - srcEnd == 0)
20
+ throw new Error("Input string had zero length or was all whitespace");
21
+ if (load<u16>(srcStart) != BRACE_LEFT) throw new Error("Expected '{' at start of object at position " + (srcEnd - srcStart).toString());
22
+ if (load<u16>(srcEnd - 2) != BRACE_RIGHT) throw new Error("Expected '}' at end of object at position " + (srcEnd - srcStart).toString());
18
23
 
19
24
  srcStart += 2;
20
25
  while (srcStart < srcEnd) {
@@ -24,13 +29,10 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
24
29
  if (isKey) {
25
30
  keyStart = lastIndex;
26
31
  keyEnd = srcStart;
27
- // console.log("Key: " + ptrToStr(keyStart, keyEnd));
32
+ // console.log("Key: " + ptrToStr(lastIndex, srcStart));
28
33
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
29
- srcStart += 2;
30
- // while (isSpace((code = load<u16>((srcStart += 2))))) {
31
- // /* empty */
32
- // }
33
- // if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcStart - srcPtr).toString());
34
+ while (isSpace((code = load<u16>((srcStart += 2))))) { }
35
+ if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcEnd - srcStart).toString());
34
36
  isKey = false;
35
37
  } else {
36
38
  // console.log("Got key start");
@@ -81,10 +83,13 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
81
83
  srcStart += 2;
82
84
  while (srcStart < srcEnd) {
83
85
  const code = load<u16>(srcStart);
84
- if (code == BRACE_RIGHT) {
86
+ if (code == QUOTE) {
87
+ srcStart += 2;
88
+ while (!(load<u16>(srcStart) == QUOTE && load<u16>(srcStart - 2) != BACK_SLASH)) srcStart += 2;
89
+ } else if (code == BRACE_RIGHT) {
85
90
  if (--depth == 0) {
86
91
  // console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
87
- out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
92
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, (srcStart += 2), dst));
88
93
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
89
94
  keyStart = 0;
90
95
  // while (isSpace(load<u16>(srcStart))) {
@@ -104,7 +109,7 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
104
109
  if (code == BRACKET_RIGHT) {
105
110
  if (--depth == 0) {
106
111
  // console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
107
- out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
112
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, (srcStart += 2), dst));
108
113
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
109
114
  keyStart = 0;
110
115
  // while (isSpace(load<u16>((srcStart += 2)))) {
@@ -118,7 +123,7 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
118
123
  } else if (code == CHAR_T) {
119
124
  if (load<u64>(srcStart) == 28429475166421108) {
120
125
  // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
121
- out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 8, dst));
126
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(srcStart, (srcStart += 8), dst));
122
127
  // while (isSpace(load<u16>((srcStart += 2)))) {
123
128
  // /* empty */
124
129
  // }
@@ -129,7 +134,7 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
129
134
  } else if (code == CHAR_F) {
130
135
  if (load<u64>(srcStart, 2) == 28429466576093281) {
131
136
  // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
132
- out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 10, dst));
137
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(srcStart, (srcStart += 10), dst));
133
138
  // while (isSpace(load<u16>((srcStart += 2)))) {
134
139
  // /* empty */
135
140
  // }
@@ -140,7 +145,7 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
140
145
  } else if (code == CHAR_N) {
141
146
  if (load<u64>(srcStart) == 30399761348886638) {
142
147
  // console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
143
- out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 8, dst));
148
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(srcStart, (srcStart += 8), dst));
144
149
  // while (isSpace(load<u16>((srcStart += 2)))) {
145
150
  /* empty */
146
151
  // }
@@ -148,6 +153,10 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
148
153
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
149
154
  keyStart = 0;
150
155
  }
156
+ } else if (isSpace(code)) {
157
+ srcStart += 2;
158
+ } else {
159
+ throw new Error("Unexpected character in JSON object '" + String.fromCharCode(code) + "' at position " + (srcEnd - srcStart).toString());
151
160
  }
152
161
  }
153
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "1.0.0-beta.10",
3
+ "version": "1.0.0-beta.11",
4
4
  "author": "Jairus Tanaka",
5
5
  "repository": {
6
6
  "type": "git",
@@ -12,6 +12,7 @@
12
12
  "@types/node": "^22.13.1",
13
13
  "as-bench": "JairusSW/as-bench",
14
14
  "as-console": "^7.0.0",
15
+ "as-test": "^0.4.0-beta.3",
15
16
  "assemblyscript": "^0.27.34",
16
17
  "assemblyscript-prettier": "^3.0.1",
17
18
  "prettier": "^3.5.0",