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;

Reply via email to