This is an automated email from the ASF dual-hosted git repository.
tbonelee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push:
new 76793932d5 [MINOR] Backport braces depth guard for React tooling
(#5528)
76793932d5 is described below
commit 76793932d50779bd2543db97467f8c3398649f75
Author: YONGJAE LEE (이용재) <[email protected]>
AuthorDate: Sun Oct 11 16:17:01 2026 +0900
[MINOR] Backport braces depth guard for React tooling (#5528)
---
.github/workflows/frontend.yml | 5 +-
.github/workflows/npm-audit-remediation.yml | 37 +-
.../projects/zeppelin-react/README.md | 10 +-
.../projects/zeppelin-react/audit-ci.jsonc | 35 ++
.../projects/zeppelin-react/package-lock.json | 543 +++++++++++++++++++++
.../projects/zeppelin-react/package.json | 5 +
.../zeppelin-react/patches/braces+3.0.3.patch | 236 +++++++++
.../zeppelin-react/scripts/check-braces-patch.cjs | 46 ++
8 files changed, 911 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index 37a4d1a438..4d00b10243 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -42,7 +42,10 @@ jobs:
# TODO: Add zeppelin-web-angular root audit after Angular version
upgrade and stabilization
- name: Run npm audit on zeppelin-react
working-directory: zeppelin-web-angular/projects/zeppelin-react
- run: npm ci --ignore-scripts && npm audit --audit-level=high
+ run: |
+ npm ci --ignore-scripts --no-audit
+ npm run apply:patches
+ npm run audit
run-playwright-e2e-tests:
runs-on: ubuntu-24.04
diff --git a/.github/workflows/npm-audit-remediation.yml
b/.github/workflows/npm-audit-remediation.yml
index 841bf3aab2..f66ad1b104 100644
--- a/.github/workflows/npm-audit-remediation.yml
+++ b/.github/workflows/npm-audit-remediation.yml
@@ -22,6 +22,11 @@ on:
pull_request:
paths:
- '.github/workflows/npm-audit-remediation.yml'
+ - 'zeppelin-web-angular/projects/zeppelin-react/audit-ci.jsonc'
+ - 'zeppelin-web-angular/projects/zeppelin-react/patches/**'
+ -
'zeppelin-web-angular/projects/zeppelin-react/scripts/check-braces-patch.cjs'
+ - 'zeppelin-web-angular/projects/zeppelin-react/package.json'
+ - 'zeppelin-web-angular/projects/zeppelin-react/package-lock.json'
concurrency:
group: npm-audit-remediation
@@ -61,6 +66,12 @@ jobs:
with:
node-version-file: 'zeppelin-web-angular/.nvmrc'
+ - name: Install and verify patched dependencies
+ working-directory: ${{ env.PACKAGE_DIRECTORY }}
+ run: |
+ npm ci --ignore-scripts --no-audit
+ npm run apply:patches
+
- id: audit
name: Check npm audit
working-directory: ${{ env.PACKAGE_DIRECTORY }}
@@ -72,11 +83,16 @@ jobs:
audit_status=$?
set -e
- if [[ ${audit_status} -eq 0 ]]; then
+ if npm run audit; then
echo "needs_remediation=false" >> "${GITHUB_OUTPUT}"
exit 0
fi
+ if [[ ${audit_status} -eq 0 ]]; then
+ echo "::error::Audit policy failed without a reported
vulnerability"
+ exit 1
+ fi
+
vulnerable_count=$(node - "${RUNNER_TEMP}/npm-audit-before.json"
<<'NODE'
const fs = require('fs');
const report = JSON.parse(fs.readFileSync(process.argv[2], 'utf8'));
@@ -104,7 +120,19 @@ jobs:
- name: Generate a lockfile-only fix
if: steps.audit.outputs.needs_remediation == 'true'
working-directory: ${{ env.PACKAGE_DIRECTORY }}
- run: npm audit fix --package-lock-only --ignore-scripts
--audit-level=high
+ shell: bash
+ run: |
+ # npm audit fix still exits nonzero while the locally patched braces
+ # release is reported as vulnerable. The policy gate below checks
+ # that every other high/critical finding was actually fixed.
+ set +e
+ npm audit fix --package-lock-only --ignore-scripts --audit-level=high
+ fix_status=$?
+ set -e
+ if [[ ${fix_status} -ne 0 ]] && git diff --quiet --
package-lock.json; then
+ echo "::error::npm audit fix failed without updating the lockfile"
+ exit "${fix_status}"
+ fi
- name: Verify the generated diff
if: steps.audit.outputs.needs_remediation == 'true'
@@ -128,7 +156,8 @@ jobs:
working-directory: ${{ env.PACKAGE_DIRECTORY }}
run: |
npm ci --ignore-scripts --no-audit
- npm audit --audit-level=high
+ npm run apply:patches
+ npm run audit
npm run lint
npm test
npm run build
@@ -274,7 +303,7 @@ jobs:
echo
echo '- `npm ci --ignore-scripts --no-audit` in
`zeppelin-web-angular`'
echo '- `npm ci --ignore-scripts --no-audit` in
`zeppelin-web-angular/projects/zeppelin-react`'
- echo '- `npm audit --audit-level=high`'
+ echo '- `npm run apply:patches` and `npm run audit`'
echo '- `npm run lint`'
echo '- `npm test`'
echo '- `npm run build`'
diff --git a/zeppelin-web-angular/projects/zeppelin-react/README.md
b/zeppelin-web-angular/projects/zeppelin-react/README.md
index 9536a85420..2bf7fcd197 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/README.md
+++ b/zeppelin-web-angular/projects/zeppelin-react/README.md
@@ -16,6 +16,15 @@ React micro-frontend that runs alongside the Angular host
via [Webpack Module Fe
- Design Document: [Micro Frontend Migration (Angular to React)
Proposal](https://cwiki.apache.org/confluence/display/ZEPPELIN/Micro+Frontend+Migration%28Angular+to+React%29+Proposal)
+## Temporary braces security patch
+
+`[email protected]` has no published fix for
[GHSA-vfj7-8cjw-p6xm](https://github.com/advisories/GHSA-vfj7-8cjw-p6xm).
+`patches/braces+3.0.3.patch` backports the depth guards from
[micromatch/braces#72](https://github.com/micromatch/braces/pull/72) at
`28d440b5dd449dbf1fe6f3506cf94ecca4d02660`. The patch changes only the five
affected `lib/` files in the published 3.0.3 package; it does not import
unrelated unreleased changes on the upstream branch.
+
+Normal `npm ci` runs the `postinstall` patch and its regression check. When
installing with `--ignore-scripts`, run `npm run apply:patches` explicitly
before using the package. `npm run audit` retains the high-severity gate but
temporarily permits only the two affected development-tool paths in
`audit-ci.jsonc`, until 2026-12-04 00:00 UTC. The npm audit report still
identifies 3.0.3 as vulnerable because it cannot inspect local patches.
+
+After upstream publishes a fixed version, update the lockfile, remove the
patch and audit exceptions, and restore the unmodified audit command.
+
## React mount infrastructure (Angular side)
The Angular host's `src/app/share/react-mount/` exports two pieces:
@@ -166,4 +175,3 @@ export function mount(element: HTMLElement, props: Props):
ReactMountHandle;
an inline object literal) so identity is stable when nothing changed.
Every exposed module must return the handle contract from `mount`. The
directive assigns the return value straight to its handle, so returning a bare
unmount function makes the next prop change throw.
-
diff --git a/zeppelin-web-angular/projects/zeppelin-react/audit-ci.jsonc
b/zeppelin-web-angular/projects/zeppelin-react/audit-ci.jsonc
new file mode 100644
index 0000000000..4072cb472e
--- /dev/null
+++ b/zeppelin-web-angular/projects/zeppelin-react/audit-ci.jsonc
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+{
+ "high": true,
+ "report-type": "summary",
+ "allowlist": [
+ {
+
"GHSA-vfj7-8cjw-p6xm|patch-package>find-yarn-workspace-root>micromatch>braces":
{
+ "active": true,
+ "notes": "braces 3.0.3 is patched locally from micromatch/braces#72;
remove after a fixed release",
+ "expiry": "2026-12-04"
+ }
+ },
+ {
+
"GHSA-vfj7-8cjw-p6xm|webpack-dev-server>http-proxy-middleware>micromatch>braces":
{
+ "active": true,
+ "notes": "braces 3.0.3 is patched locally from micromatch/braces#72;
remove after a fixed release",
+ "expiry": "2026-12-04"
+ }
+ }
+ ]
+}
diff --git a/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
b/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
index 81f23343ec..e7fdc495d4 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
+++ b/zeppelin-web-angular/projects/zeppelin-react/package-lock.json
@@ -34,6 +34,7 @@
"@typescript-eslint/parser": "^8.56.1",
"@vitest/coverage-v8": "4.1.11",
"@vitest/eslint-plugin": "^1.6.27",
+ "audit-ci": "7.1.0",
"css-loader": "6.8.0",
"eslint": "^9.28.0",
"eslint-plugin-react": "^7.37.5",
@@ -41,6 +42,7 @@
"globals": "^15.14.0",
"html-webpack-plugin": "5.5.0",
"jsdom": "29.1.1",
+ "patch-package": "8.0.1",
"style-loader": "3.3.0",
"ts-loader": "9.6.2",
"typescript": "5.9.3",
@@ -2706,6 +2708,13 @@
"dev": true,
"license": "Apache-2.0"
},
+ "node_modules/@yarnpkg/lockfile": {
+ "version": "1.1.0",
+ "resolved":
"https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
+ "integrity":
"sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
"node_modules/@zeppelin/notebook-core": {
"resolved": "../zeppelin-notebook-core",
"link": true
@@ -3190,6 +3199,30 @@
"node": ">= 0.4"
}
},
+ "node_modules/audit-ci": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/audit-ci/-/audit-ci-7.1.0.tgz",
+ "integrity":
"sha512-PjjEejlST57S/aDbeWLic0glJ8CNl/ekY3kfGFPMrPkmuaYaDKcMH0F9x9yS9Vp6URhuefSCubl/G0Y2r6oP0g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "escape-string-regexp": "^4.0.0",
+ "event-stream": "4.0.1",
+ "jju": "^1.4.0",
+ "jsonstream-next": "^3.0.0",
+ "readline-transform": "1.0.0",
+ "semver": "^7.0.0",
+ "tslib": "^2.0.0",
+ "yargs": "^17.0.0"
+ },
+ "bin": {
+ "audit-ci": "dist/bin.js"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved":
"https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -3585,6 +3618,22 @@
"node": ">=6.0"
}
},
+ "node_modules/ci-info": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
+ "integrity":
"sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/classnames": {
"version": "2.5.1",
"resolved":
"https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
@@ -3604,6 +3653,21 @@
"node": ">= 10.0"
}
},
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity":
"sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/clone-deep": {
"version": "4.0.1",
"resolved":
"https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -4283,6 +4347,13 @@
"node": ">= 0.4"
}
},
+ "node_modules/duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity":
"sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -4297,6 +4368,13 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved":
"https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity":
"sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -4827,6 +4905,22 @@
"node": ">= 0.6"
}
},
+ "node_modules/event-stream": {
+ "version": "4.0.1",
+ "resolved":
"https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz",
+ "integrity":
"sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "duplexer": "^0.1.1",
+ "from": "^0.1.7",
+ "map-stream": "0.0.7",
+ "pause-stream": "^0.0.11",
+ "split": "^1.0.1",
+ "stream-combiner": "^0.2.2",
+ "through": "^2.3.8"
+ }
+ },
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@@ -5094,6 +5188,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/find-yarn-workspace-root": {
+ "version": "2.0.0",
+ "resolved":
"https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
+ "integrity":
"sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "micromatch": "^4.0.2"
+ }
+ },
"node_modules/flat": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
@@ -5170,6 +5274,28 @@
"node": ">= 0.8"
}
},
+ "node_modules/from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity":
"sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity":
"sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -5236,6 +5362,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved":
"https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity":
"sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved":
"https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@@ -5950,6 +6086,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved":
"https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity":
"sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/is-generator-function": {
"version": "1.1.2",
"resolved":
"https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
@@ -6394,6 +6540,13 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
+ "node_modules/jju": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
+ "integrity":
"sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -6485,6 +6638,26 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/json-stable-stringify": {
+ "version": "1.3.0",
+ "resolved":
"https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz",
+ "integrity":
"sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "isarray": "^2.0.5",
+ "jsonify": "^0.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved":
"https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
@@ -6501,6 +6674,56 @@
"string-convert": "^0.2.0"
}
},
+ "node_modules/jsonfile": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz",
+ "integrity":
"sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsonify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz",
+ "integrity":
"sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==",
+ "dev": true,
+ "license": "Public Domain",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity":
"sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "dev": true,
+ "engines": [
+ "node >= 0.2.0"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/jsonstream-next": {
+ "version": "3.0.0",
+ "resolved":
"https://registry.npmjs.org/jsonstream-next/-/jsonstream-next-3.0.0.tgz",
+ "integrity":
"sha512-aAi6oPhdt7BKyQn1SrIIGZBt0ukKuOUE1qV6kJ3GgioSOYzsRc8z9Hfr1BVmacA/jLe9nARfmgMGgn68BqIAgg==",
+ "dev": true,
+ "license": "(MIT OR Apache-2.0)",
+ "dependencies": {
+ "jsonparse": "^1.2.0",
+ "through2": "^4.0.2"
+ },
+ "bin": {
+ "jsonstream-next": "bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/jsx-ast-utils": {
"version": "3.3.5",
"resolved":
"https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
@@ -6537,6 +6760,16 @@
"node": ">=0.10.0"
}
},
+ "node_modules/klaw-sync": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
+ "integrity":
"sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.11"
+ }
+ },
"node_modules/launch-editor": {
"version": "2.14.1",
"resolved":
"https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.1.tgz",
@@ -6947,6 +7180,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/map-stream": {
+ "version": "0.0.7",
+ "resolved":
"https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
+ "integrity":
"sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved":
"https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -7087,6 +7327,16 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity":
"sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -7539,6 +7789,82 @@
"tslib": "^2.0.3"
}
},
+ "node_modules/patch-package": {
+ "version": "8.0.1",
+ "resolved":
"https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz",
+ "integrity":
"sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@yarnpkg/lockfile": "^1.1.0",
+ "chalk": "^4.1.2",
+ "ci-info": "^3.7.0",
+ "cross-spawn": "^7.0.3",
+ "find-yarn-workspace-root": "^2.0.0",
+ "fs-extra": "^10.0.0",
+ "json-stable-stringify": "^1.0.2",
+ "klaw-sync": "^6.0.0",
+ "minimist": "^1.2.6",
+ "open": "^7.4.2",
+ "semver": "^7.5.3",
+ "slash": "^2.0.0",
+ "tmp": "^0.2.4",
+ "yaml": "^2.2.2"
+ },
+ "bin": {
+ "patch-package": "index.js"
+ },
+ "engines": {
+ "node": ">=14",
+ "npm": ">5"
+ }
+ },
+ "node_modules/patch-package/node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity":
"sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/patch-package/node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity":
"sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/patch-package/node_modules/open": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
+ "integrity":
"sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0",
+ "is-wsl": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved":
"https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -7584,6 +7910,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/pause-stream": {
+ "version": "0.0.11",
+ "resolved":
"https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity":
"sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
+ "dev": true,
+ "license": [
+ "MIT",
+ "Apache2"
+ ],
+ "dependencies": {
+ "through": "~2.3"
+ }
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved":
"https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -8665,6 +9004,21 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved":
"https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity":
"sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/readdirp": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
@@ -8679,6 +9033,16 @@
"url": "https://paulmillr.com/funding/"
}
},
+ "node_modules/readline-transform": {
+ "version": "1.0.0",
+ "resolved":
"https://registry.npmjs.org/readline-transform/-/readline-transform-1.0.0.tgz",
+ "integrity":
"sha512-7KA6+N9IGat52d83dvxnApAWN+MtVb1MiVuMR/cf1O4kYsJG+g/Aav0AHcHKsb6StinayfPLne0+fMX2sOzAKg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
@@ -8789,6 +9153,16 @@
"strip-ansi": "^6.0.1"
}
},
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved":
"https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity":
"sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved":
"https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@@ -9472,6 +9846,16 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity":
"sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/source-map": {
"version": "0.6.1",
"resolved":
"https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -9503,6 +9887,19 @@
"source-map": "^0.6.0"
}
},
+ "node_modules/split": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+ "integrity":
"sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "through": "2"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/ssf": {
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
@@ -9553,12 +9950,48 @@
"node": ">= 0.4"
}
},
+ "node_modules/stream-combiner": {
+ "version": "0.2.2",
+ "resolved":
"https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
+ "integrity":
"sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "duplexer": "~0.1.1",
+ "through": "~2.3.4"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved":
"https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity":
"sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
"node_modules/string-convert": {
"version": "0.2.1",
"resolved":
"https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
"integrity":
"sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==",
"license": "MIT"
},
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved":
"https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity":
"sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/string.prototype.matchall": {
"version": "4.0.12",
"resolved":
"https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
@@ -9866,6 +10299,23 @@
"node": ">=12.22"
}
},
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity":
"sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/through2": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
+ "integrity":
"sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readable-stream": "3"
+ }
+ },
"node_modules/thunky": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
@@ -9937,6 +10387,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tmp": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz",
+ "integrity":
"sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved":
"https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -10308,6 +10768,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved":
"https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity":
"sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -11062,6 +11532,24 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity":
"sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -11155,6 +11643,61 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity":
"sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yaml": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz",
+ "integrity":
"sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/eemeli"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.3",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz",
+ "integrity":
"sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved":
"https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity":
"sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved":
"https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/zeppelin-web-angular/projects/zeppelin-react/package.json
b/zeppelin-web-angular/projects/zeppelin-react/package.json
index 191cc6cfef..783b6193a8 100644
--- a/zeppelin-web-angular/projects/zeppelin-react/package.json
+++ b/zeppelin-web-angular/projects/zeppelin-react/package.json
@@ -5,6 +5,9 @@
"*.css"
],
"scripts": {
+ "postinstall": "npm run apply:patches",
+ "apply:patches": "patch-package && node scripts/check-braces-patch.cjs",
+ "audit": "node scripts/check-braces-patch.cjs && audit-ci --config
audit-ci.jsonc",
"start": "webpack serve --config webpack.config.js --mode development",
"build": "webpack --config webpack.config.js --mode production",
"dev": "webpack serve --config webpack.config.js --mode development",
@@ -41,6 +44,7 @@
"@typescript-eslint/parser": "^8.56.1",
"@vitest/coverage-v8": "4.1.11",
"@vitest/eslint-plugin": "^1.6.27",
+ "audit-ci": "7.1.0",
"css-loader": "6.8.0",
"eslint": "^9.28.0",
"eslint-plugin-react": "^7.37.5",
@@ -48,6 +52,7 @@
"globals": "^15.14.0",
"html-webpack-plugin": "5.5.0",
"jsdom": "29.1.1",
+ "patch-package": "8.0.1",
"style-loader": "3.3.0",
"ts-loader": "9.6.2",
"typescript": "5.9.3",
diff --git
a/zeppelin-web-angular/projects/zeppelin-react/patches/braces+3.0.3.patch
b/zeppelin-web-angular/projects/zeppelin-react/patches/braces+3.0.3.patch
new file mode 100644
index 0000000000..809532547e
--- /dev/null
+++ b/zeppelin-web-angular/projects/zeppelin-react/patches/braces+3.0.3.patch
@@ -0,0 +1,236 @@
+diff --git a/node_modules/braces/lib/compile.js
b/node_modules/braces/lib/compile.js
+index dce69be..945a78b 100644
+--- a/node_modules/braces/lib/compile.js
++++ b/node_modules/braces/lib/compile.js
+@@ -2,9 +2,15 @@
+
+ const fill = require('fill-range');
+ const utils = require('./utils');
++const { MAX_DEPTH } = require('./constants');
+
+ const compile = (ast, options = {}) => {
+- const walk = (node, parent = {}) => {
++ const maxDepth = Number.isFinite(options.maxDepth) ? Math.min(MAX_DEPTH,
options.maxDepth) : MAX_DEPTH;
++
++ const walk = (node, parent = {}, depth = 0) => {
++ if (node.nodes && depth > maxDepth) {
++ throw new RangeError(`AST depth (${depth}), exceeds max depth
(${maxDepth})`);
++ }
+ const invalidBlock = utils.isInvalidBrace(parent);
+ const invalidNode = node.invalid === true && options.escapeInvalid ===
true;
+ const invalid = invalidBlock === true || invalidNode === true;
+@@ -47,14 +53,14 @@ const compile = (ast, options = {}) => {
+
+ if (node.nodes) {
+ for (const child of node.nodes) {
+- output += walk(child, node);
++ output += walk(child, node, child.nodes ? depth + 1 : depth);
+ }
+ }
+
+ return output;
+ };
+
+- return walk(ast);
++ return walk(ast, {}, ast.type === 'root' ? 0 : 1);
+ };
+
+ module.exports = compile;
+diff --git a/node_modules/braces/lib/constants.js
b/node_modules/braces/lib/constants.js
+index 2bb3b88..c237099 100644
+--- a/node_modules/braces/lib/constants.js
++++ b/node_modules/braces/lib/constants.js
+@@ -1,6 +1,7 @@
+ 'use strict';
+
+ module.exports = {
++ MAX_DEPTH: 100,
+ MAX_LENGTH: 10000,
+
+ // Digits
+diff --git a/node_modules/braces/lib/expand.js
b/node_modules/braces/lib/expand.js
+index 35b2c41..8211c5b 100644
+--- a/node_modules/braces/lib/expand.js
++++ b/node_modules/braces/lib/expand.js
+@@ -3,6 +3,7 @@
+ const fill = require('fill-range');
+ const stringify = require('./stringify');
+ const utils = require('./utils');
++const { MAX_DEPTH } = require('./constants');
+
+ const append = (queue = '', stash = '', enclose = false) => {
+ const result = [];
+@@ -30,19 +31,31 @@ const append = (queue = '', stash = '', enclose = false)
=> {
+ return utils.flatten(result);
+ };
+
++const queueOwner = node => {
++ if (node.type === 'brace' || node.type === 'root' || !node.parent) return
node;
++
++ const seen = new Set();
++ while (node.type !== 'brace' && node.type !== 'root' && node.parent) {
++ if (seen.has(node)) {
++ throw new RangeError('AST parent chain contains a cycle');
++ }
++ seen.add(node);
++ node = node.parent;
++ }
++ return node;
++};
++
+ const expand = (ast, options = {}) => {
+ const rangeLimit = options.rangeLimit === undefined ? 1000 :
options.rangeLimit;
++ const maxDepth = Number.isFinite(options.maxDepth) ? Math.min(MAX_DEPTH,
options.maxDepth) : MAX_DEPTH;
+
+- const walk = (node, parent = {}) => {
++ const walk = (node, parent = {}, depth = 0) => {
++ if (node.nodes && depth > maxDepth) {
++ throw new RangeError(`AST depth (${depth}), exceeds max depth
(${maxDepth})`);
++ }
+ node.queue = [];
+
+- let p = parent;
+- let q = parent.queue;
+-
+- while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
+- p = p.parent;
+- q = p.queue;
+- }
++ const q = queueOwner(parent).queue;
+
+ if (node.invalid || node.dollar) {
+ q.push(append(q.pop(), stringify(node, options)));
+@@ -72,13 +85,7 @@ const expand = (ast, options = {}) => {
+ }
+
+ const enclose = utils.encloseBrace(node);
+- let queue = node.queue;
+- let block = node;
+-
+- while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
+- block = block.parent;
+- queue = block.queue;
+- }
++ const queue = queueOwner(node).queue;
+
+ for (let i = 0; i < node.nodes.length; i++) {
+ const child = node.nodes[i];
+@@ -100,14 +107,14 @@ const expand = (ast, options = {}) => {
+ }
+
+ if (child.nodes) {
+- walk(child, node);
++ walk(child, node, child.nodes ? depth + 1 : depth);
+ }
+ }
+
+ return queue;
+ };
+
+- return utils.flatten(walk(ast));
++ return utils.flatten(walk(ast, {}, ast.type === 'root' ? 0 : 1));
+ };
+
+ module.exports = expand;
+diff --git a/node_modules/braces/lib/parse.js
b/node_modules/braces/lib/parse.js
+index 3a6988e..d4c2c72 100644
+--- a/node_modules/braces/lib/parse.js
++++ b/node_modules/braces/lib/parse.js
+@@ -7,6 +7,7 @@ const stringify = require('./stringify');
+ */
+
+ const {
++ MAX_DEPTH,
+ MAX_LENGTH,
+ CHAR_BACKSLASH, /* \ */
+ CHAR_BACKTICK, /* ` */
+@@ -35,6 +36,7 @@ const parse = (input, options = {}) => {
+
+ const opts = options || {};
+ const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH,
opts.maxLength) : MAX_LENGTH;
++ const maxDepth = Number.isFinite(opts.maxDepth) ? Math.min(MAX_DEPTH,
opts.maxDepth) : MAX_DEPTH;
+ if (input.length > max) {
+ throw new SyntaxError(`Input length (${input.length}), exceeds max
characters (${max})`);
+ }
+@@ -47,6 +49,7 @@ const parse = (input, options = {}) => {
+ const length = input.length;
+ let index = 0;
+ let depth = 0;
++ let nesting = 0;
+ let value;
+
+ /**
+@@ -143,6 +146,10 @@ const parse = (input, options = {}) => {
+ */
+
+ if (value === CHAR_LEFT_PARENTHESES) {
++ if (nesting + 1 > maxDepth) {
++ throw new SyntaxError(`Input depth (${nesting + 1}), exceeds max
depth (${maxDepth})`);
++ }
++ nesting++;
+ block = push({ type: 'paren', nodes: [] });
+ stack.push(block);
+ push({ type: 'text', value });
+@@ -156,6 +163,7 @@ const parse = (input, options = {}) => {
+ }
+ block = stack.pop();
+ push({ type: 'text', value });
++ nesting--;
+ block = stack[stack.length - 1];
+ continue;
+ }
+@@ -195,6 +203,10 @@ const parse = (input, options = {}) => {
+ */
+
+ if (value === CHAR_LEFT_CURLY_BRACE) {
++ if (nesting + 1 > maxDepth) {
++ throw new SyntaxError(`Input depth (${nesting + 1}), exceeds max
depth (${maxDepth})`);
++ }
++ nesting++;
+ depth++;
+
+ const dollar = prev.value && prev.value.slice(-1) === '$' ||
block.dollar === true;
+@@ -231,6 +243,7 @@ const parse = (input, options = {}) => {
+
+ push({ type, value });
+ depth--;
++ nesting--;
+
+ block = stack[stack.length - 1];
+ continue;
+diff --git a/node_modules/braces/lib/stringify.js
b/node_modules/braces/lib/stringify.js
+index 8bcf872..651849c 100644
+--- a/node_modules/braces/lib/stringify.js
++++ b/node_modules/braces/lib/stringify.js
+@@ -1,9 +1,15 @@
+ 'use strict';
+
+ const utils = require('./utils');
++const { MAX_DEPTH } = require('./constants');
+
+ module.exports = (ast, options = {}) => {
+- const stringify = (node, parent = {}) => {
++ const maxDepth = Number.isFinite(options.maxDepth) ? Math.min(MAX_DEPTH,
options.maxDepth) : MAX_DEPTH;
++
++ const stringify = (node, parent = {}, depth = 0) => {
++ if (node.nodes && depth > maxDepth) {
++ throw new RangeError(`AST depth (${depth}), exceeds max depth
(${maxDepth})`);
++ }
+ const invalidBlock = options.escapeInvalid &&
utils.isInvalidBrace(parent);
+ const invalidNode = node.invalid === true && options.escapeInvalid ===
true;
+ let output = '';
+@@ -21,12 +27,11 @@ module.exports = (ast, options = {}) => {
+
+ if (node.nodes) {
+ for (const child of node.nodes) {
+- output += stringify(child);
++ output += stringify(child, undefined, child.nodes ? depth + 1 :
depth);
+ }
+ }
+ return output;
+ };
+
+- return stringify(ast);
++ return stringify(ast, {}, ast.type === 'root' ? 0 : 1);
+ };
+-
diff --git
a/zeppelin-web-angular/projects/zeppelin-react/scripts/check-braces-patch.cjs
b/zeppelin-web-angular/projects/zeppelin-react/scripts/check-braces-patch.cjs
new file mode 100644
index 0000000000..22a9dbcc9f
--- /dev/null
+++
b/zeppelin-web-angular/projects/zeppelin-react/scripts/check-braces-patch.cjs
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const assert = require('node:assert/strict');
+const braces = require('braces');
+
+assert.equal(require('braces/package.json').version, '3.0.3');
+
+const nested = depth => '{'.repeat(depth) + 'a' + '}'.repeat(depth);
+const boundary = braces.parse(nested(100));
+assert.doesNotThrow(() => braces.compile(boundary));
+assert.doesNotThrow(() => braces.expand(braces.parse(nested(100))));
+assert.doesNotThrow(() => braces.stringify(boundary));
+assert.throws(() => braces.parse(nested(101)), /exceeds max depth \(100\)/);
+assert.doesNotThrow(() => braces.parse('('.repeat(100) + 'a' +
')'.repeat(100)));
+assert.throws(() => braces.parse('('.repeat(101) + 'a' + ')'.repeat(101)),
/exceeds max depth \(100\)/);
+assert.throws(() => braces.parse('{{a,b},c}', { maxDepth: 1.5 }), /exceeds max
depth \(1.5\)/);
+
+const deepAst = () => {
+ let node = { type: 'text', value: 'a' };
+ for (let depth = 0; depth < 101; depth++) {
+ node = { type: 'brace', open: true, close: true, nodes: [node] };
+ }
+ return node;
+};
+
+for (const method of ['compile', 'expand', 'stringify']) {
+ assert.throws(() => braces[method](deepAst()), /exceeds max depth \(100\)/,
method);
+}
+
+assert.equal(braces.stringify(braces.parse('{{a}}'), { escapeInvalid: true }),
'{{a}}');
+console.log('braces depth patch verified');