fix: prevent Menu.buildFromTemplate with empty array (#23308)
Prevent issues with menu creation and subsequent pane focus from menu bar by preventing menus from being created from an empty array. I can't conceive a valid use case for this, since if one wants to remove a menu they should be be passing null to win.setMenu() or calling win.removeMenu(). This issue is also specific to top-level menus, and not submenus, so the new check and exception is scoped to top-level menus.
This commit is contained in:
		
					parent
					
						
							
								448017b9ee
							
						
					
				
			
			
				commit
				
					
						f50f725a9c
					
				
			
		
					 3 changed files with 19 additions and 2 deletions
				
			
		| 
						 | 
					@ -16,7 +16,7 @@ const MenuItem = function (options) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  this.submenu = this.submenu || roles.getDefaultSubmenu(this.role);
 | 
					  this.submenu = this.submenu || roles.getDefaultSubmenu(this.role);
 | 
				
			||||||
  if (this.submenu != null && this.submenu.constructor !== Menu) {
 | 
					  if (this.submenu != null && this.submenu.constructor !== Menu) {
 | 
				
			||||||
    this.submenu = Menu.buildFromTemplate(this.submenu);
 | 
					    this.submenu = Menu.buildFromTemplate(this.submenu, true);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (this.type == null && this.submenu != null) {
 | 
					  if (this.type == null && this.submenu != null) {
 | 
				
			||||||
    this.type = 'submenu';
 | 
					    this.type = 'submenu';
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,13 +173,17 @@ Menu.setApplicationMenu = function (menu) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Menu.buildFromTemplate = function (template) {
 | 
					Menu.buildFromTemplate = function (template, isSubmenu = false) {
 | 
				
			||||||
  if (!Array.isArray(template)) {
 | 
					  if (!Array.isArray(template)) {
 | 
				
			||||||
    throw new TypeError('Invalid template for Menu: Menu template must be an array');
 | 
					    throw new TypeError('Invalid template for Menu: Menu template must be an array');
 | 
				
			||||||
 | 
					  } else if (!isSubmenu && template.length === 0) {
 | 
				
			||||||
 | 
					    throw new TypeError('Invalid template for Menu: Menu template must be an non-empty array');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!areValidTemplateItems(template)) {
 | 
					  if (!areValidTemplateItems(template)) {
 | 
				
			||||||
    throw new TypeError('Invalid template for MenuItem: must have at least one of label, role or type');
 | 
					    throw new TypeError('Invalid template for MenuItem: must have at least one of label, role or type');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const filtered = removeExtraSeparators(template);
 | 
					  const filtered = removeExtraSeparators(template);
 | 
				
			||||||
  const sorted = sortTemplate(filtered);
 | 
					  const sorted = sortTemplate(filtered);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,12 +86,25 @@ describe('Menu module', function () {
 | 
				
			||||||
        Menu.buildFromTemplate([{ visible: true }]);
 | 
					        Menu.buildFromTemplate([{ visible: true }]);
 | 
				
			||||||
      }).to.throw(/Invalid template for MenuItem: must have at least one of label, role or type/);
 | 
					      }).to.throw(/Invalid template for MenuItem: must have at least one of label, role or type/);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('does throw exception for undefined', () => {
 | 
					    it('does throw exception for undefined', () => {
 | 
				
			||||||
      expect(() => {
 | 
					      expect(() => {
 | 
				
			||||||
        Menu.buildFromTemplate([undefined as any]);
 | 
					        Menu.buildFromTemplate([undefined as any]);
 | 
				
			||||||
      }).to.throw(/Invalid template for MenuItem: must have at least one of label, role or type/);
 | 
					      }).to.throw(/Invalid template for MenuItem: must have at least one of label, role or type/);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('throws when an empty array is passed as a template', () => {
 | 
				
			||||||
 | 
					      expect(() => {
 | 
				
			||||||
 | 
					        Menu.buildFromTemplate([]);
 | 
				
			||||||
 | 
					      }).to.throw(/Invalid template for Menu: Menu template must be an non-empty array/);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('throws when an non-array is passed as a template', () => {
 | 
				
			||||||
 | 
					      expect(() => {
 | 
				
			||||||
 | 
					        Menu.buildFromTemplate('hello' as any);
 | 
				
			||||||
 | 
					      }).to.throw(/Invalid template for Menu: Menu template must be an array/);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe('Menu sorting and building', () => {
 | 
					    describe('Menu sorting and building', () => {
 | 
				
			||||||
      describe('sorts groups', () => {
 | 
					      describe('sorts groups', () => {
 | 
				
			||||||
        it('does a simple sort', () => {
 | 
					        it('does a simple sort', () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue