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 108536f4e0 [ZEPPELIN-6534] Escape note name before building clone-name
RegExp
108536f4e0 is described below
commit 108536f4e0eef785ba855927a94701627d333d98
Author: κΉμλ <[email protected]>
AuthorDate: Sun Jul 19 02:06:59 2026 +0900
[ZEPPELIN-6534] Escape note name before building clone-name RegExp
### What is this PR for?
Cloning a note whose name contains a regular-expression metacharacter (for
example `[`, `(`, or a trailing backslash) threw an uncaught `SyntaxError` when
the clone dialog opened, so the suggested clone name was never generated and
the dialog was broken for that note. `cloneNoteName()` interpolated the note
name directly into a `RegExp` source without escaping it. This PR escapes the
note name before building the `RegExp`, so any note name is matched literally.
While verifying the fix in the running UI, a second, pre-existing defect
surfaced in the same note view: opening **any** note logged an uncaught
`TypeError: Cannot read properties of undefined (reading 'forEach')`. In
`ngOnInit`, the `queryParamMap` subscription runs synchronously via
`startWith()` and calls `onParagraphSearch()` before the `<at>ViewChildren`
`QueryList` (`listOfNotebookParagraphComponent`) is populated (it is only
available after `ngAfterViewInit`). This PR guards th [...]
### What type of PR is it?
Bug Fix
### Todos
* [x] Escape note name before building the clone-name `RegExp`
* [x] Guard `onParagraphSearch()` against an uninitialized
`<at>ViewChildren` `QueryList`
### What is the Jira issue?
[ZEPPELIN-6534](https://issues.apache.org/jira/browse/ZEPPELIN-6534)
### How should this be tested?
* `cd zeppelin-web-angular && npm run lint`
* Create a note named `report[2024` (or `foo(bar`) and click **Clone**:
before the fix the dialog throws `SyntaxError` and no name is suggested; after
the fix it suggests `report[2024 1` and clones normally. Clone-name numbering
for ordinary names is unchanged (escaping is a no-op when there are no
metacharacters).
* Open any note with the browser devtools console open: before the fix a
`forEach` `TypeError` is logged on load; after the fix the console is clean.
### Questions:
* Does the license files need to be updated? No
* Are there breaking changes for older versions? No
* Does this need documentation? No
Closes #5318 from kimyenac/ZEPPELIN-6534.
Signed-off-by: ChanHo Lee <[email protected]>
---
.../src/app/pages/workspace/notebook/notebook.component.ts | 2 +-
.../src/app/share/note-create/note-create.component.ts | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git
a/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.ts
b/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.ts
index d76bca003e..408ca1af28 100644
---
a/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.ts
+++
b/zeppelin-web-angular/src/app/pages/workspace/notebook/notebook.component.ts
@@ -272,7 +272,7 @@ export class NotebookComponent extends
MessageListenersManager implements OnInit
}
onParagraphSearch(term: string) {
- this.listOfNotebookParagraphComponent.forEach(comp =>
comp.highlightMatches(term || ''));
+ this.listOfNotebookParagraphComponent?.forEach(comp =>
comp.highlightMatches(term || ''));
}
saveParagraph(id: string) {
diff --git
a/zeppelin-web-angular/src/app/share/note-create/note-create.component.ts
b/zeppelin-web-angular/src/app/share/note-create/note-create.component.ts
index ff0dbae759..96f510ffd4 100644
--- a/zeppelin-web-angular/src/app/share/note-create/note-create.component.ts
+++ b/zeppelin-web-angular/src/app/share/note-create/note-create.component.ts
@@ -64,7 +64,8 @@ export class NoteCreateComponent extends
MessageListenersManager implements OnIn
const lastIndex = cloneNote.name.lastIndexOf(' ');
const endsWithNumber = !!cloneNote.name.match('^.+?\\s\\d$');
const noteNamePrefix = endsWithNumber ? cloneNote.name.slice(0, lastIndex)
: cloneNote.name;
- const regexp = new RegExp(`^${noteNamePrefix}.+`);
+ const escapedNoteNamePrefix =
noteNamePrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ const regexp = new RegExp(`^${escapedNoteNamePrefix}.+`);
this.noteListService.notes.flatList.forEach(note => {
const noteName = note.path;