2cdae04ddc1e46cdfc2e5e8cf479cbbbb616ad10 chmalee Tue Sep 22 15:55:10 2026 -0700 htmlSanitize tooltips before printing them into the page, refs #38226 diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index 93dd575e16d..c6c02b7d62a 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -4489,58 +4489,59 @@ // CGIs now use HTML tags, e.g. "<b>Transcript:</b> ENST00000297261.7<br><b>Strand:</b>" title = rightClick.mouseOverToLabel(decodeURIComponent(title)); if (title.length > maxLength) { title = title.substring(0, maxLength) + "..."; } if (isHgc) { // For GTEx gene and UniProt mouseovers, replace title (which may be a tissue name) with // item (gene) name. Also need to unescape the urlencoded characters and the + sign. let a = /i=([^&]+)/.exec(href); if (a && a[1]) { title = decodeURIComponent(a[1].replace(/\+/g, " ")); } } + var titleHtml = htmlEncode(title); if (displayItemFunctions) { - o[rightClick.makeImgTag("magnify.png") + " Zoom to " + title] = { + o[rightClick.makeImgTag("magnify.png") + " Zoom to " + titleHtml] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "selectWholeGene"); return true; } }; - o[rightClick.makeImgTag("highlight.png") + " Highlight " + title] = + o[rightClick.makeImgTag("highlight.png") + " Highlight " + titleHtml] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "highlightItem"); return true; } }; var itemForColor = rightClick.itemFromHref(href); if (hgTracks.canColorItems && itemForColor) { - o[rightClick.makeImgTag("palette.png") + " Color " + title + "..."] = + o[rightClick.makeImgTag("palette.png") + " Color " + titleHtml + "..."] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "colorThisItem"); return true; } }; if (rightClick.findItemColor(itemForColor.track, itemForColor.name)) { o[rightClick.makeImgTag("palette.png") + - " Remove color from " + title] = + " Remove color from " + titleHtml] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "removeItemColor"); return true; } }; } } //o[rightClick.makeImgTag("highlight.png") + " Highlight THIS item"] = // { onclick: function(menuItemClicked, menuObject) { // rightClick.hit(menuItemClicked, menuObject, // "highlightThisItem"); // return true; // } // }; @@ -4593,60 +4594,60 @@ rightClick.hit(menuItemClicked, menuObject, "zoomCodon", {name: name, table: table, 'chrom': hgTracks.chromName}); return true;} }; o[rightClick.makeImgTag("magnify.png")+" Enter exon to zoom to..."] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "zoomExon", {name: name, table: table, 'chrom': hgTracks.chromName}); return true;} }; } } } - o[rightClick.makeImgTag("dnaIcon.png")+" Get DNA for "+title] = { + o[rightClick.makeImgTag("dnaIcon.png")+" Get DNA for "+titleHtml] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "getDna"); return true; } }; } o[rightClick.makeImgTag("bookOut.png")+ " Open details page in new window..."] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "openLink"); return true; } }; any = true; } if (href && href.length > 0 && href.indexOf("i=mergedItem") === -1) { // Add "Show details..." item if (title.indexOf("Click to alter ") === 0) { // suppress the "Click to alter..." items } else if (rightClick.selectedMenuItem.href.indexOf("cgi-bin/hgTracks") !== -1) { // suppress menu items for hgTracks links (e.g. Next/Prev map items). } else { var item; if (title === "zoomInMore") // avoid showing menu item that says // "Show details for zoomInMore..." (redmine 2447) item = rightClick.makeImgTag("book.png") + " Show details..."; else item = rightClick.makeImgTag("book.png")+" Show details for "+ - title + "..."; + htmlEncode(title) + "..."; o[item] = {onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked,menuObject,"followLink"); return true; } }; any = true; } } if (any) { menu.push($.contextMenu.separator); menu.push(o); } } }