From 16a12e4e25b5e1e13dfea27b70669236651b15fc Mon Sep 17 00:00:00 2001 From: luoxiao Date: Fri, 8 Nov 2024 17:17:31 +0800 Subject: [PATCH] [fix]innerhtml escapeHTML --- src/common/_utils/util.js | 23 +++++++++++++ src/mapboxgl/search/Search.vue | 4 +-- src/mapboxgl/tdt/search/TdtSearchViewModel.js | 32 ++++++++----------- .../layer/animate-marker/marker/Marker.ts | 7 ++-- .../marker/RotatingTextBorderMarker.ts | 6 ++-- 5 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/common/_utils/util.js b/src/common/_utils/util.js index d4c61d6a..3bc257ec 100644 --- a/src/common/_utils/util.js +++ b/src/common/_utils/util.js @@ -6,6 +6,28 @@ import omit from 'omit.js'; import tinyColor from 'tinycolor2'; import { min, max as statisticsMax, mean, sum, mode, median, variance, standardDeviation } from 'simple-statistics'; +export function escapeHTML(strings) { + var result = ''; + for (var i = 0; i < strings.length; i++) { + result += strings[i]; + if (i + 1 < arguments.length) { + var value = arguments[i + 1] || ''; + result += String(value).replace(/[&<>"'/]/g, + function (s) { + return { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''', + '/': '/' + }[s]; + }); + } + } + return result; +} + export function getDateTime(timeType) { return geti18n().d(new Date(), timeType.replace(/\+/g, '_')); } @@ -245,3 +267,4 @@ export function numberEqual(num1, num2, precision = 10E-6) { } export const statisticFunctions = { min, max: statisticsMax, mean, sum, mode, median, variance, standardDeviation, count: fieldValues => fieldValues.length }; + diff --git a/src/mapboxgl/search/Search.vue b/src/mapboxgl/search/Search.vue index 6ee17828..30cd1987 100644 --- a/src/mapboxgl/search/Search.vue +++ b/src/mapboxgl/search/Search.vue @@ -112,7 +112,7 @@ import SmIcon from 'vue-iclient/src/common/icon/Icon.vue'; import SmInput from 'vue-iclient/src/common/input/Input.vue'; import Message from 'vue-iclient/src/common/message/Message.js'; import TablePopup from 'vue-iclient/src/common/table-popup/TablePopup.vue'; -import { setPopupArrowStyle } from 'vue-iclient/src/common/_utils/util'; +import { setPopupArrowStyle, escapeHTML } from 'vue-iclient/src/common/_utils/util'; import isEqual from 'lodash.isequal'; export default { @@ -307,7 +307,7 @@ export default { emitEvent && this.$emit('clear-search-result'); }, searchResultListClicked(data, event) { - const searchKey = event.target.innerHTML; + const searchKey = escapeHTML`${event.target.innerHTML}`; this.isSuggestion = false; this.viewModel.getFeatureInfo(searchKey, data); }, diff --git a/src/mapboxgl/tdt/search/TdtSearchViewModel.js b/src/mapboxgl/tdt/search/TdtSearchViewModel.js index 05e14a82..277ef854 100644 --- a/src/mapboxgl/tdt/search/TdtSearchViewModel.js +++ b/src/mapboxgl/tdt/search/TdtSearchViewModel.js @@ -16,6 +16,7 @@ import { import bbox from '@turf/bbox'; import transformScale from '@turf/transform-scale'; import { geti18n } from 'vue-iclient/src/common/_lang/index'; +import { escapeHTML } from 'vue-iclient/src/common/_utils/util'; export default class TdtSearchViewModel extends mapboxgl.Evented { constructor(options) { @@ -126,25 +127,18 @@ export default class TdtSearchViewModel extends mapboxgl.Evented { `; const content = document.createElement('div'); content.className = 'content'; - content.innerHTML = ` - ${ - from === 'Point' - ? `
-
${geti18n().t('tdtSearch.phone')}: ${data.phone || geti18n().t('tdtSearch.noData')}
-
${geti18n().t('tdtSearch.address')}: ${data.address || - geti18n().t('tdtSearch.noData')}
-
` - : '' -} - ${ - from === 'LineString' - ? `
-
${geti18n().t('tdtSearch.transport')}: ${data.address || - geti18n().t('tdtSearch.noData')}
-
` - : '' -} - `; + const pointHtml = escapeHTML`
+
${geti18n().t('tdtSearch.phone')}: ${data.phone || geti18n().t('tdtSearch.noData')}
+
${geti18n().t('tdtSearch.address')}: ${ + data.address || geti18n().t('tdtSearch.noData') + }
+
`; + const lineHtml = escapeHTML`
+
${geti18n().t('tdtSearch.transport')}: ${ + data.address || geti18n().t('tdtSearch.noData') + }
+
`; + content.innerHTML = from === 'Point' ? pointHtml : from === 'LineString' ? lineHtml : ''; const group = document.createElement('div'); group.className = 'operate-group'; const startItem = document.createElement('div'); diff --git a/src/mapboxgl/web-map/layer/animate-marker/marker/Marker.ts b/src/mapboxgl/web-map/layer/animate-marker/marker/Marker.ts index 758cf8e6..7be142c2 100644 --- a/src/mapboxgl/web-map/layer/animate-marker/marker/Marker.ts +++ b/src/mapboxgl/web-map/layer/animate-marker/marker/Marker.ts @@ -1,5 +1,6 @@ import { FeatureCollection, Feature } from 'geojson'; -import { getColorWithOpacity } from 'vue-iclient/src/common/_utils/util'; +// @ts-ignore +import { getColorWithOpacity, escapeHTML } from 'vue-iclient/src/common/_utils/util'; interface markerOptions { width?: number; @@ -40,7 +41,7 @@ export default abstract class Marker { for (let i = 0; i < name.length; i++) { const properties = this.features.features[i] && this.features.features[i].properties; if (properties && properties[textField]) { - name[i].innerHTML = properties[textField]; + name[i].innerHTML = escapeHTML`${properties[textField]}`; } else { name[i].innerHTML = ''; } @@ -82,7 +83,7 @@ export default abstract class Marker { this.options.textFontSize && (nameContainer.style.fontSize = this.options.textFontSize + 'px'); const nameSpan = document.createElement('span'); nameSpan.className = `sm-component-animate-marker__${className} sm-component-animate-marker__name`; - nameSpan.innerHTML = name || ''; + nameSpan.innerHTML = escapeHTML`${name}` || ''; nameContainer.appendChild(nameSpan); return nameContainer; } diff --git a/src/mapboxgl/web-map/layer/animate-marker/marker/RotatingTextBorderMarker.ts b/src/mapboxgl/web-map/layer/animate-marker/marker/RotatingTextBorderMarker.ts index f195e22d..def552fc 100644 --- a/src/mapboxgl/web-map/layer/animate-marker/marker/RotatingTextBorderMarker.ts +++ b/src/mapboxgl/web-map/layer/animate-marker/marker/RotatingTextBorderMarker.ts @@ -1,4 +1,6 @@ import { FeatureCollection } from 'geojson'; +// @ts-ignore +import { escapeHTML } from 'vue-iclient/src/common/_utils/util'; import Marker from './Marker'; interface markerOptions { @@ -47,7 +49,7 @@ export default class RotatingTextBorderMarker extends Marker { for (let i = 0; i < name.length; i++) { let properties = this.features.features[i] && this.features.features[i].properties; if (properties && properties[textField]) { - name[i].innerHTML = properties[textField]; + name[i].innerHTML = escapeHTML`${properties[textField]}`; } else { name[i].innerHTML = ''; } @@ -92,7 +94,7 @@ export default class RotatingTextBorderMarker extends Marker { } let span = document.createElement('span'); span.className = 'sm-component-animate-marker__text'; - span.innerHTML = name || ''; + span.innerHTML = escapeHTML`${name}` || ''; border.appendChild(span); if (this.options.colors && this.options.colors.length && this.options.colors.length > 0) { markerContainer.style.setProperty('--border-color', this.options.colors[0]);