@wenathlan/argan 2.0.174 → 2.0.176

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/dns.ts +25 -2
  2. package/package.json +32 -32
package/dns.ts CHANGED
@@ -420,12 +420,35 @@ const NAMEFIELDS: Record<string, readonly number[]> = {
420
420
  /** TTL unit multipliers for the RFC 2308 spellings ("1h30m"). */
421
421
  const TTLUNITS: Record<string, number> = { s: 1, m: 60, h: 3600, d: 86400, w: 604800 };
422
422
 
423
+ /** The bounded seat of the ttl grammar: the longest ttl spelling any zone file and any registrar answer carries sits far below this ceiling, so a hostile unbounded digit run (the polynomial-redos wall the code scanning gate flagged — the match over `\d+[smhdw]` walked cubic backtracking on a run of zeros the unit never ends) never reaches the engine. */
424
+ const TTLTOKENLIMIT = 32;
425
+
423
426
  /** Parses a TTL token: plain seconds ("300") or unit spellings ("1h30m"). */
424
427
  function parseTtl(token: string): number {
428
+ /* the bounded seat guards both regex paths at once — the plain-seconds
429
+ * test and the unit scan — before any pattern touches the input. */
430
+ if (token.length > TTLTOKENLIMIT) return Number.NaN;
425
431
  if (/^\d+$/.test(token)) return Number.parseInt(token, 10);
426
432
  const lower = token.toLowerCase();
427
- const units = lower.match(/\d+[smhdw]/g);
428
- if (!units || units.join("") !== lower) return Number.NaN;
433
+ // the linear unit scan (the redos heal): the old global regex walked
434
+ // back over every digit of a unit-less token before advancing, a
435
+ // polynomial cost on crafted inputs - the manual walk visits each
436
+ // character exactly once and answers the same units list.
437
+ const units: string[] = [];
438
+ let index = 0;
439
+ while (index < lower.length) {
440
+ const start = index;
441
+ while (index < lower.length && lower.charCodeAt(index) >= 48 && lower.charCodeAt(index) <= 57) index += 1;
442
+ if (index === start) {
443
+ index += 1;
444
+ continue;
445
+ }
446
+ if (index < lower.length && TTLUNITS[lower[index]] !== undefined) {
447
+ units.push(lower.slice(start, index + 1));
448
+ }
449
+ index += 1;
450
+ }
451
+ if (units.length === 0 || units.join("") !== lower) return Number.NaN;
429
452
  return units.reduce((total, part) => total + Number.parseInt(part, 10) * TTLUNITS[part.slice(-1)], 0);
430
453
  }
431
454
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wenathlan/argan",
3
- "version": "2.0.174",
3
+ "version": "2.0.176",
4
4
  "private": false,
5
5
  "description": "argan is the DNS and gateway library of the wenathlan family: zones, records, dnssec and handshake — the system network library whose site shares the unified database. The envelope distributes the documentation set, the zero-build site and the tests directory as one package.",
6
6
  "license": "GPL-3.0-only",
@@ -15,10 +15,10 @@
15
15
  "restore:entry": "node -e \"const{readFileSync}=require('node:fs');const{execSync}=require('node:child_process');const script=/script[^>]*App\\.tsx/;const triad=/family=Inter[\\s\\S]*Geist\\+Mono/;const face=(h)=>script.test(h)&&triad.test(h);if(face(readFileSync('index.html','utf8'))){console.log('index.html already rides the source face');process.exit(0)}if(!face(execSync('git show HEAD:./index.html',{encoding:'utf8'}))){console.error('refusing: HEAD index.html is not the canonical source face yet (script App.tsx + the font triad) - land the source-face fix first; nothing was touched');process.exit(1)}execSync('git checkout -- index.html',{stdio:'inherit'});console.log('index.html restored from HEAD (the source face)')\""
16
16
  },
17
17
  "dependencies": {
18
- "@ai-sdk/openai": "^4.0.111",
19
- "@ai-sdk/openai-compatible": "^3.0.87",
20
- "@ai-sdk/provider-utils": "^5.0.76",
21
- "@anthropic-ai/sdk": "^1.7.0",
18
+ "@ai-sdk/openai": "^4.0.114",
19
+ "@ai-sdk/openai-compatible": "^3.0.90",
20
+ "@ai-sdk/provider-utils": "^5.0.79",
21
+ "@anthropic-ai/sdk": "^1.8.0",
22
22
  "@biomejs/biome": "^2.6.6",
23
23
  "@capacitor/android": "^8.6.0",
24
24
  "@capacitor/cli": "^8.6.0",
@@ -95,7 +95,7 @@
95
95
  "@wenathlan/saddle": "~2.0.173",
96
96
  "@wenathlan/vault": "~2.0.173",
97
97
  "add": "^2.0.9",
98
- "ai": "^7.0.166",
98
+ "ai": "^7.0.169",
99
99
  "autoprefixer": "^10.6.2",
100
100
  "axios": "^1.21.1",
101
101
  "baseline-browser-mapping": "^2.11.35",
@@ -121,7 +121,7 @@
121
121
  "fast-check": "^4.10.2",
122
122
  "fast-uri": "^4.2.3",
123
123
  "follow-redirects": "^1.16.3",
124
- "framer-motion": "^14.11.1",
124
+ "framer-motion": "^14.12.0",
125
125
  "glob": "^14.0.4",
126
126
  "gsap": "^3.15.1",
127
127
  "hono": "^4.13.17",
@@ -130,15 +130,15 @@
130
130
  "js-yaml": "^5.5.0",
131
131
  "jsdom": "^31.0.0",
132
132
  "katex": "^0.19.1",
133
- "minimatch": "^11.0.5",
134
- "motion": "^14.11.1",
133
+ "minimatch": "^11.0.6",
134
+ "motion": "^14.12.0",
135
135
  "mysql2": "^3.24.6",
136
136
  "nanoid": "^6.0.2",
137
137
  "next": "^16.4.6",
138
138
  "next-auth": "^4.24.15",
139
- "next-intl": "^4.14.9",
139
+ "next-intl": "^4.14.10",
140
140
  "next-themes": "^0.4.6",
141
- "openai": "^7.54.0",
141
+ "openai": "^7.55.0",
142
142
  "p-limit": "^7.3.3",
143
143
  "p-retry": "^9.0.0",
144
144
  "playwright": "^1.65.0",
@@ -188,10 +188,10 @@
188
188
  "zustand": "^5.1.0"
189
189
  },
190
190
  "devDependencies": {
191
- "@ai-sdk/openai": "^4.0.111",
192
- "@ai-sdk/openai-compatible": "^3.0.87",
193
- "@ai-sdk/provider-utils": "^5.0.76",
194
- "@anthropic-ai/sdk": "^1.7.0",
191
+ "@ai-sdk/openai": "^4.0.114",
192
+ "@ai-sdk/openai-compatible": "^3.0.90",
193
+ "@ai-sdk/provider-utils": "^5.0.79",
194
+ "@anthropic-ai/sdk": "^1.8.0",
195
195
  "@biomejs/biome": "^2.6.6",
196
196
  "@capacitor/android": "^8.6.0",
197
197
  "@capacitor/cli": "^8.6.0",
@@ -272,7 +272,7 @@
272
272
  "@wenathlan/stealthhead": "~2.0.173",
273
273
  "@wenathlan/vault": "~2.0.173",
274
274
  "add": "^2.0.9",
275
- "ai": "^7.0.166",
275
+ "ai": "^7.0.169",
276
276
  "autoprefixer": "^10.6.2",
277
277
  "axios": "^1.21.1",
278
278
  "baseline-browser-mapping": "^2.11.35",
@@ -298,7 +298,7 @@
298
298
  "fast-check": "^4.10.2",
299
299
  "fast-uri": "^4.2.3",
300
300
  "follow-redirects": "^1.16.3",
301
- "framer-motion": "^14.11.1",
301
+ "framer-motion": "^14.12.0",
302
302
  "glob": "^14.0.4",
303
303
  "gsap": "^3.15.1",
304
304
  "hono": "^4.13.17",
@@ -307,15 +307,15 @@
307
307
  "js-yaml": "^5.5.0",
308
308
  "jsdom": "^31.0.0",
309
309
  "katex": "^0.19.1",
310
- "minimatch": "^11.0.5",
311
- "motion": "^14.11.1",
310
+ "minimatch": "^11.0.6",
311
+ "motion": "^14.12.0",
312
312
  "mysql2": "^3.24.6",
313
313
  "nanoid": "^6.0.2",
314
314
  "next": "^16.4.6",
315
315
  "next-auth": "^4.24.15",
316
- "next-intl": "^4.14.9",
316
+ "next-intl": "^4.14.10",
317
317
  "next-themes": "^0.4.6",
318
- "openai": "^7.54.0",
318
+ "openai": "^7.55.0",
319
319
  "p-limit": "^7.3.3",
320
320
  "p-retry": "^9.0.0",
321
321
  "playwright": "^1.65.0",
@@ -365,10 +365,10 @@
365
365
  "zustand": "^5.1.0"
366
366
  },
367
367
  "overrides": {
368
- "@ai-sdk/openai": "^4.0.111",
369
- "@ai-sdk/openai-compatible": "^3.0.87",
370
- "@ai-sdk/provider-utils": "^5.0.76",
371
- "@anthropic-ai/sdk": "^1.7.0",
368
+ "@ai-sdk/openai": "^4.0.114",
369
+ "@ai-sdk/openai-compatible": "^3.0.90",
370
+ "@ai-sdk/provider-utils": "^5.0.79",
371
+ "@anthropic-ai/sdk": "^1.8.0",
372
372
  "@biomejs/biome": "^2.6.6",
373
373
  "@capacitor/android": "^8.6.0",
374
374
  "@capacitor/cli": "^8.6.0",
@@ -445,7 +445,7 @@
445
445
  "@wenathlan/saddle": "~2.0.173",
446
446
  "@wenathlan/vault": "~2.0.173",
447
447
  "add": "^2.0.9",
448
- "ai": "^7.0.166",
448
+ "ai": "^7.0.169",
449
449
  "autoprefixer": "^10.6.2",
450
450
  "axios": "^1.21.1",
451
451
  "baseline-browser-mapping": "^2.11.35",
@@ -471,7 +471,7 @@
471
471
  "fast-check": "^4.10.2",
472
472
  "fast-uri": "^4.2.3",
473
473
  "follow-redirects": "^1.16.3",
474
- "framer-motion": "^14.11.1",
474
+ "framer-motion": "^14.12.0",
475
475
  "glob": "^14.0.4",
476
476
  "gsap": "^3.15.1",
477
477
  "hono": "^4.13.17",
@@ -480,16 +480,16 @@
480
480
  "js-yaml": "^5.5.0",
481
481
  "jsdom": "^31.0.0",
482
482
  "katex": "^0.19.1",
483
- "lucide-react": "^1.70.0",
484
- "minimatch": "^11.0.5",
485
- "motion": "^14.11.1",
483
+ "lucide-react": "^1.71.0",
484
+ "minimatch": "^11.0.6",
485
+ "motion": "^14.12.0",
486
486
  "mysql2": "^3.24.6",
487
487
  "nanoid": "^6.0.2",
488
488
  "next": "^16.4.6",
489
489
  "next-auth": "^4.24.15",
490
- "next-intl": "^4.14.9",
490
+ "next-intl": "^4.14.10",
491
491
  "next-themes": "^0.4.6",
492
- "openai": "^7.54.0",
492
+ "openai": "^7.55.0",
493
493
  "p-limit": "^7.3.3",
494
494
  "p-retry": "^9.0.0",
495
495
  "playwright": "^1.65.0",