teptris 0.3.9 → 0.3.10

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +23 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teptris",
3
- "version": "0.3.9",
3
+ "version": "0.3.10",
4
4
  "description": "TOML for JavaScript/TypeScript at libteptris speed (WebAssembly, no fallback) - version tracks the engine ({engine}.{iteration}; npm semver is 3-part)",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -51,6 +51,20 @@ function parseDateTime(str) {
51
51
  const RFC3339 =
52
52
  /^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?)?$|^\d{2}:\d{2}:\d{2}(\.\d+)?$/;
53
53
 
54
+ // cheap charset pre-check before the RFC 3339 regex: datetimes start
55
+ // with a digit and only ever contain digits, date/time punctuation
56
+ // and TZ marks - rejects nearly all plain strings without the regex
57
+ const DATETIME_CHARS = /[0-9Tt: .+Zz-]/;
58
+ const utf8 = new TextDecoder("utf-8");
59
+ function maybeRfc3339(v) {
60
+ const c0 = v.charCodeAt(0);
61
+ if (!(c0 >= 48 && c0 <= 57)) return false;
62
+ for (let i = 1; i < v.length; i++) {
63
+ if (!DATETIME_CHARS.test(v[i])) return false;
64
+ }
65
+ return true;
66
+ }
67
+
54
68
  function buildValue(mod, b, key, v, errs) {
55
69
  const kp = key == null ? 0 : cstr(mod, key);
56
70
  try {
@@ -122,7 +136,9 @@ export function initApi(mod) {
122
136
  let value = null, error = null;
123
137
  if (st === 0) {
124
138
  const jptr = mod._teptris_wasm_json();
125
- value = JSON.parse(UTF8ToString(jptr));
139
+ const jlen = mod._teptris_wasm_json_len();
140
+ value = JSON.parse(
141
+ utf8.decode(mod.HEAPU8.subarray(jptr, jptr + jlen)));
126
142
  mod._teptris_wasm_free(jptr);
127
143
  } else {
128
144
  error = {
@@ -225,7 +241,7 @@ export function initApi(mod) {
225
241
  }
226
242
  if (typeof v === "bigint") { byte(3); i64(v); return; }
227
243
  if (typeof v === "string") {
228
- if (RFC3339.test(v)) {
244
+ if (maybeRfc3339(v) && RFC3339.test(v)) {
229
245
  const dt = parseDateTime(v);
230
246
  wkey(k);
231
247
  ensure(27);
@@ -252,11 +268,13 @@ export function initApi(mod) {
252
268
  (typeof v === "string" || typeof v === "number" ||
253
269
  typeof v === "boolean" || typeof v === "bigint"));
254
270
  const members = (o, inline) => {
255
- const ents = Object.entries(o);
256
- for (const [k, v] of ents) {
271
+ const keys = Object.keys(o);
272
+ for (let i = 0; i < keys.length; i++) {
273
+ const k = keys[i], v = o[k];
257
274
  if (isScalar(v)) scalar(k, v);
258
275
  }
259
- for (const [k, v] of ents) {
276
+ for (let i = 0; i < keys.length; i++) {
277
+ const k = keys[i], v = o[k];
260
278
  if (isScalar(v)) continue;
261
279
  if (v === null || v === undefined) {
262
280
  throw new Error("null/undefined cannot round-trip through TOML");