dsh-unlag 1.9.44 → 1.9.46

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/README.md +9 -1
  2. package/index.js +17 -2
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -78,5 +78,13 @@ dsh plugin install dsh-unlag
78
78
  ## 测试
79
79
 
80
80
  ```sh
81
- node --test test/*.test.mjs
81
+ npm test
82
82
  ```
83
+
84
+ 对着正在运行的 App 走一遍真实判定(页面半、宿主半都是线上代码,用的是 App 现在渲染的启动清单;只回答「能不能刷」,绝不按按钮):
85
+
86
+ ```sh
87
+ npm run smoke
88
+ ```
89
+
90
+ 没有 App 在监听时打印 `skip` 并退出 0。
package/index.js CHANGED
@@ -110,6 +110,15 @@ const MAX_SCRIPT_BYTES = 64 * 1024 * 1024
110
110
  * the compile happens under it: what a check keeps per body is the ids it names, never its text.
111
111
  */
112
112
  const MAX_TOTAL_SCRIPT_BYTES = 128 * 1024 * 1024
113
+ /**
114
+ * How large the request that carries the list may be. The list itself is bounded (64 addresses of at
115
+ * most 8 KB, plus JSON escaping), so a bound below that would refuse a sound startup list from a
116
+ * profile with many bundles and report it as an empty one. A body past this bound is not a list this
117
+ * app could boot from, and it is answered as such instead of being read.
118
+ */
119
+ const MAX_LIST_BODY_BYTES = 1024 * 1024
120
+ /** The body reader's answer for a request past its bound: not JSON, and not an empty list either. */
121
+ const TOO_LARGE = Symbol('too-large')
113
122
 
114
123
  /**
115
124
  * The most plugin ids one bundle address may name. A real startup list is far below this; a made-up
@@ -801,7 +810,7 @@ function buttonAllowed(req) {
801
810
  }
802
811
 
803
812
  /** Read one small JSON request body; anything unreadable answers null instead of hanging. */
804
- function readJsonBody(req, limit = 64 * 1024) {
813
+ function readJsonBody(req, limit = MAX_LIST_BODY_BYTES) {
805
814
 
806
815
  return new Promise((resolve) => {
807
816
  let size = 0
@@ -828,7 +837,7 @@ function readJsonBody(req, limit = 64 * 1024) {
828
837
  req.on('data', (chunk) => {
829
838
  size += chunk.length
830
839
  if (size > limit) {
831
- finish(null)
840
+ finish(TOO_LARGE)
832
841
  return
833
842
  }
834
843
  parts.push(chunk)
@@ -1675,6 +1684,12 @@ function serveButton(ctx, controller, config) {
1675
1684
  return sendJson(res, 200, { status: 'blocked', reason: 'list', detail: 'the plugin table is not running' })
1676
1685
  }
1677
1686
  const body = await readJsonBody(req)
1687
+ // A list larger than the bound is refused in its own words: an oversized request is not an
1688
+ // empty list, and a person told their startup list names nothing would look in the wrong place.
1689
+ if (body === TOO_LARGE) {
1690
+ log('a startup check refused the page: size (the startup list is longer than this check reads)')
1691
+ return sendJson(res, 200, { status: 'blocked', reason: 'size', detail: 'the startup list is longer than this check reads' })
1692
+ }
1678
1693
  let verdict = null
1679
1694
  try {
1680
1695
  verdict = await verifyStartup(clientModules, Array.isArray(body?.rows) ? body.rows : [])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-unlag",
3
- "version": "1.9.44",
3
+ "version": "1.9.46",
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",
@@ -50,7 +50,8 @@
50
50
  },
51
51
  "scripts": {
52
52
  "test": "for f in test/*.test.mjs; do node \"$f\" || exit 1; done",
53
- "audit": "eslint --no-config-lookup --rule '{\"no-undef\":\"error\",\"no-unused-vars\":[\"error\",{\"args\":\"none\",\"caughtErrors\":\"none\"}]}' --global window --global document --global navigator --global location --global sessionStorage --global localStorage --global fetch --global Response --global Request --global URL --global URLSearchParams --global AbortController --global CustomEvent --global Event --global setTimeout --global clearTimeout --global setInterval --global clearInterval --global requestAnimationFrame --global queueMicrotask --global structuredClone --global Buffer --global process --global console index.js client.js"
53
+ "audit": "eslint --no-config-lookup --rule '{\"no-undef\":\"error\",\"no-unused-vars\":[\"error\",{\"args\":\"none\",\"caughtErrors\":\"none\"}]}' --global window --global document --global navigator --global location --global sessionStorage --global localStorage --global fetch --global Response --global Request --global URL --global URLSearchParams --global AbortController --global CustomEvent --global Event --global setTimeout --global clearTimeout --global setInterval --global clearInterval --global requestAnimationFrame --global queueMicrotask --global structuredClone --global Buffer --global process --global console index.js client.js",
54
+ "smoke": "node scripts/live-smoke.mjs"
54
55
  },
55
56
  "devDependencies": {
56
57
  "eslint": "9.39.0"