dsh-unlag 1.9.36 → 1.9.37

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 (3) hide show
  1. package/client.js +3 -2
  2. package/index.js +13 -0
  3. package/package.json +1 -1
package/client.js CHANGED
@@ -15,8 +15,8 @@ window.__ModuleLoader__.load({
15
15
  * repeating one generic sentence.
16
16
  */
17
17
  const REASONS = zh
18
- ? { list: '读不到启动信息', slow: '启动信息读得太慢', row: '启动信息不完整', src: '启动脚本没有地址', graph: '已装插件清单读不到', plugin: '有插件已不在运行', script: '启动脚本读不到', empty: '启动脚本是空的', covers: '启动脚本缺插件', parse: '启动脚本内容不完整', verify: '插件后端没有应答' }
19
- : { list: 'startup info is unavailable', slow: 'the startup list answered too slowly', row: 'startup info is incomplete', src: 'a startup script has no address', graph: 'the plugin list cannot be read', plugin: 'a plugin is no longer running', script: 'a startup script cannot be read', empty: 'a startup script is empty', covers: 'a startup script misses a plugin', parse: 'a startup script is incomplete', verify: 'the plugin is not answering' };
18
+ ? { list: '读不到启动信息', slow: '启动信息读得太慢', row: '启动信息不完整', src: '启动脚本没有地址', graph: '已装插件清单读不到', plugin: '有插件已不在运行', script: '启动脚本读不到', empty: '启动脚本是空的', covers: '启动脚本缺插件', parse: '启动脚本内容不完整', size: '启动脚本太大', verify: '插件后端没有应答' }
19
+ : { list: 'startup info is unavailable', slow: 'the startup list answered too slowly', row: 'startup info is incomplete', src: 'a startup script has no address', graph: 'the plugin list cannot be read', plugin: 'a plugin is no longer running', script: 'a startup script cannot be read', empty: 'a startup script is empty', covers: 'a startup script misses a plugin', parse: 'a startup script is incomplete', size: 'a startup script is too large', verify: 'the plugin is not answering' };
20
20
 
21
21
  /** The last reason a readiness check refused for, or null after a check that passed. */
22
22
  let holdReason = null;
@@ -244,6 +244,7 @@ window.__ModuleLoader__.load({
244
244
  missing: 'script', // ui-copy-ignore
245
245
  network: 'script', // ui-copy-ignore
246
246
  parse: 'parse', // ui-copy-ignore
247
+ size: 'script', // ui-copy-ignore
247
248
  register: 'plugin', // ui-copy-ignore
248
249
  slow: 'slow', // ui-copy-ignore
249
250
  dependencies: 'covers',
package/index.js CHANGED
@@ -91,6 +91,14 @@ const DEFAULT_ROOTS = [join(homedir(), '.dsh', 'plugins')]
91
91
  const MAX_DEFERRALS = 40
92
92
  const MAX_STARTUP_ROWS = 64
93
93
  const MAX_STARTUP_ROW_CHARS = 4096
94
+ /**
95
+ * The largest one startup script may be before a check refuses it. A real client bundle is far
96
+ * below this; a body past it is either a mistake or an attempt to make a check read (and compile)
97
+ * an unbounded amount of text inside the process that owns every running turn.
98
+ */
99
+ const MAX_SCRIPT_BYTES = 8 * 1024 * 1024
100
+ /** The same bound for one whole startup list, so a list of large bodies cannot add up either. */
101
+ const MAX_TOTAL_SCRIPT_BYTES = 32 * 1024 * 1024
94
102
 
95
103
  /**
96
104
  * The most plugin ids one bundle address may name. A real startup list is far below this; a made-up
@@ -1468,6 +1476,7 @@ export async function verifyStartupRows(graph, fetchBody, rows, budgetMs = MAX_V
1468
1476
  const listed = new Set()
1469
1477
  const bodies = []
1470
1478
  const began = Date.now()
1479
+ let totalBytes = 0
1471
1480
  for (const item of wanted) {
1472
1481
  if (Date.now() - began > budgetMs) {
1473
1482
  return { status: 'blocked', reason: 'slow', detail: 'the startup list took longer than this check waits' }
@@ -1485,6 +1494,10 @@ export async function verifyStartupRows(graph, fetchBody, rows, budgetMs = MAX_V
1485
1494
  }
1486
1495
  const bytes = Buffer.from(await response.arrayBuffer())
1487
1496
  if (bytes.length === 0) return { status: 'blocked', reason: 'empty', detail: `${item.url} answers an empty body` }
1497
+ totalBytes += bytes.length
1498
+ if (bytes.length > MAX_SCRIPT_BYTES || totalBytes > MAX_TOTAL_SCRIPT_BYTES) {
1499
+ return { status: 'blocked', reason: 'size', detail: `${item.url} answers ${String(bytes.length)} bytes; this check reads at most ${String(MAX_SCRIPT_BYTES)} per script and ${String(MAX_TOTAL_SCRIPT_BYTES)} in all` }
1500
+ }
1488
1501
  const text = bytes.toString('utf8')
1489
1502
  const complaint = parseAsScript(text, item.url)
1490
1503
  if (complaint !== null) return { status: 'blocked', reason: 'parse', detail: `${item.url}: ${complaint}` }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-unlag",
3
- "version": "1.9.36",
3
+ "version": "1.9.37",
4
4
  "type": "module",
5
5
  "description": "A press applies plugin edits right away and brings a laggy interface back; automatic reloading stays off unless you turn it on, so the press is the only trigger, and nothing restarts.",
6
6
  "license": "MIT",