dsh-unlag 1.9.115 → 1.9.117

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/index.js +18 -9
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -100,15 +100,20 @@ const MAX_STARTUP_ROW_CHARS = 8192
100
100
  * The largest one startup script may be before a check refuses it. The app serves a whole profile as
101
101
  * a few bundles, and those grow with every installed plugin: one profile's largest bundle measured
102
102
  * 8.7 MB, which a smaller bound refused as if it were an attack and left the page unrebuildable.
103
- * A body past this bound is a mistake or an attempt to make a check read (and compile) an unbounded
104
- * amount of text inside the process that owns every running turn.
103
+ * Compiling a body costs several times its size in memory before it is thrown away, and up to three
104
+ * checks may run at once, so the bound is set close to what a profile actually serves: this one
105
+ * measured 15.7 MB across three bundles, its largest 9.2 MB. A body past 24 MB is not a profile
106
+ * this app ships with, and reading one would let a request make the process that owns every running
107
+ * turn hold text no page boots from.
105
108
  */
106
- const MAX_SCRIPT_BYTES = 64 * 1024 * 1024
109
+ const MAX_SCRIPT_BYTES = 24 * 1024 * 1024
107
110
  /**
108
- * The same bound for one whole startup list, so a list of large bodies cannot add up either. Only
109
- * the compile happens under it: what a check keeps per body is the ids it names, never its text.
111
+ * The same bound for one whole startup list. This one bounds work, not memory: a body's text is let
112
+ * go before the next one is read, so what the list costs is summed compile time, and this profile
113
+ * measured 158 ms for 15.7 MB. A bound this far above a real profile keeps a large profile
114
+ * rebuildable while still stopping a list from asking for minutes of compiling.
110
115
  */
111
- const MAX_TOTAL_SCRIPT_BYTES = 128 * 1024 * 1024
116
+ const MAX_TOTAL_SCRIPT_BYTES = 256 * 1024 * 1024
112
117
  /**
113
118
  * How large the request that carries the list may be. The list itself is bounded (64 addresses of at
114
119
  * most 8 KB, plus JSON escaping), so a bound below that would refuse a sound startup list from a
@@ -1646,7 +1651,11 @@ function parseAsScript(body, name) {
1646
1651
  * @param fetchBody reads one script address and answers a response-like, or null when it cannot.
1647
1652
  * @param rows the startup script addresses, as the next document would request them.
1648
1653
  */
1649
- export async function verifyStartupRows(graph, fetchBody, rows, budgetMs = MAX_VERIFY_MS) {
1654
+ export async function verifyStartupRows(graph, fetchBody, rows, budgetMs = MAX_VERIFY_MS, limits = null) {
1655
+ // The bounds are the shipped ones; the argument exists so a test can work them at a size a test
1656
+ // run can afford. Anything not a usable number falls back to the shipped bound.
1657
+ const maxScriptBytes = Number.isFinite(limits?.maxScriptBytes) ? limits.maxScriptBytes : MAX_SCRIPT_BYTES
1658
+ const maxTotalBytes = Number.isFinite(limits?.maxTotalBytes) ? limits.maxTotalBytes : MAX_TOTAL_SCRIPT_BYTES
1650
1659
  // A startup list is checked against the plugin set, so a set that cannot be read at all leaves
1651
1660
  // nothing to check against: approving anyway would vouch for addresses nothing backs, and the
1652
1661
  // next document would die on the first one that answers 404. An empty set is still a readable
@@ -1742,8 +1751,8 @@ export async function verifyStartupRows(graph, fetchBody, rows, budgetMs = MAX_V
1742
1751
  }
1743
1752
  if (bytes.length === 0) return { status: 'blocked', reason: 'empty', detail: `${item.url} answers an empty body` }
1744
1753
  totalBytes += bytes.length
1745
- if (bytes.length > MAX_SCRIPT_BYTES || totalBytes > MAX_TOTAL_SCRIPT_BYTES) {
1746
- 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` }
1754
+ if (bytes.length > maxScriptBytes || totalBytes > maxTotalBytes) {
1755
+ return { status: 'blocked', reason: 'size', detail: `${item.url} answers ${String(bytes.length)} bytes; this check reads at most ${String(maxScriptBytes)} per script and ${String(maxTotalBytes)} in all` }
1747
1756
  }
1748
1757
  const text = bytes.toString('utf8')
1749
1758
  const complaint = parseAsScript(text, item.url)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-unlag",
3
- "version": "1.9.115",
3
+ "version": "1.9.117",
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",