mirror of
https://github.com/apache/superset.git
synced 2026-06-09 09:39:25 +00:00
fix(plugin-chart-echarts): sanitize series from html tags (#1126)
* fix(plugin-chart-echarts): sanitize series from html tags * use echarts html encoder
This commit is contained in:
committed by
Yongjie Zhao
parent
c160a4abde
commit
895d9d325d
@@ -30,7 +30,7 @@ import {
|
||||
BoxPlotQueryFormData,
|
||||
EchartsBoxPlotChartProps,
|
||||
} from './types';
|
||||
import { extractGroupbyLabel, getColtypesMapping } from '../utils/series';
|
||||
import { extractGroupbyLabel, getColtypesMapping, sanitizeHtml } from '../utils/series';
|
||||
import { defaultGrid, defaultTooltip, defaultYAxis } from '../defaults';
|
||||
|
||||
export default function transformProps(
|
||||
@@ -103,7 +103,9 @@ export default function transformProps(
|
||||
tooltip: {
|
||||
formatter: (param: { data: [string, number] }) => {
|
||||
const [outlierName, stats] = param.data;
|
||||
const headline = groupby ? `<p><strong>${outlierName}</strong></p>` : '';
|
||||
const headline = groupby
|
||||
? `<p><strong>${sanitizeHtml(outlierName)}</strong></p>`
|
||||
: '';
|
||||
return `${headline}${numberFormatter(stats)}`;
|
||||
},
|
||||
},
|
||||
@@ -161,7 +163,7 @@ export default function transformProps(
|
||||
value: [number, number, number, number, number, number, number, number, number[]];
|
||||
name: string;
|
||||
} = param;
|
||||
const headline = name ? `<p><strong>${name}</strong></p>` : '';
|
||||
const headline = name ? `<p><strong>${sanitizeHtml(name)}</strong></p>` : '';
|
||||
const stats = [
|
||||
`Max: ${numberFormatter(value[5])}`,
|
||||
`3rd Quartile: ${numberFormatter(value[4])}`,
|
||||
|
||||
@@ -35,7 +35,12 @@ import {
|
||||
FunnelChartTransformedProps,
|
||||
} from './types';
|
||||
import { DEFAULT_LEGEND_FORM_DATA } from '../types';
|
||||
import { extractGroupbyLabel, getChartPadding, getLegendProps } from '../utils/series';
|
||||
import {
|
||||
extractGroupbyLabel,
|
||||
getChartPadding,
|
||||
getLegendProps,
|
||||
sanitizeHtml,
|
||||
} from '../utils/series';
|
||||
import { defaultGrid, defaultTooltip } from '../defaults';
|
||||
|
||||
const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
|
||||
@@ -49,7 +54,8 @@ export function formatFunnelLabel({
|
||||
labelType: EchartsFunnelLabelTypeType;
|
||||
numberFormatter: NumberFormatter;
|
||||
}): string {
|
||||
const { name = '', value, percent } = params;
|
||||
const { name: rawName = '', value, percent } = params;
|
||||
const name = sanitizeHtml(rawName);
|
||||
const formattedValue = numberFormatter(value as number);
|
||||
const formattedPercent = percentFormatter((percent as number) / 100);
|
||||
switch (labelType) {
|
||||
|
||||
@@ -34,7 +34,7 @@ import {
|
||||
} from './types';
|
||||
import { DEFAULT_GRAPH_SERIES_OPTION } from './constants';
|
||||
import { EchartsProps } from '../types';
|
||||
import { getChartPadding, getLegendProps } from '../utils/series';
|
||||
import { getChartPadding, getLegendProps, sanitizeHtml } from '../utils/series';
|
||||
|
||||
type EdgeWithStyles = GraphEdgeItemOption & {
|
||||
lineStyle: Exclude<GraphEdgeItemOption['lineStyle'], undefined>;
|
||||
@@ -127,7 +127,9 @@ function edgeFormatter(
|
||||
): string {
|
||||
const source = Number(sourceIndex);
|
||||
const target = Number(targetIndex);
|
||||
return `${getKeyByValue(nodes, source)} > ${getKeyByValue(nodes, target)} : ${value}`;
|
||||
return `${sanitizeHtml(getKeyByValue(nodes, source))} > ${sanitizeHtml(
|
||||
getKeyByValue(nodes, target),
|
||||
)} : ${value}`;
|
||||
}
|
||||
|
||||
function getCategoryName(columnName: string, name?: DataRecordValue) {
|
||||
|
||||
@@ -40,6 +40,7 @@ import {
|
||||
getChartPadding,
|
||||
getColtypesMapping,
|
||||
getLegendProps,
|
||||
sanitizeHtml,
|
||||
} from '../utils/series';
|
||||
import { defaultGrid, defaultTooltip } from '../defaults';
|
||||
|
||||
@@ -54,7 +55,8 @@ export function formatPieLabel({
|
||||
labelType: EchartsPieLabelType;
|
||||
numberFormatter: NumberFormatter;
|
||||
}): string {
|
||||
const { name = '', value, percent } = params;
|
||||
const { name: rawName = '', value, percent } = params;
|
||||
const name = sanitizeHtml(rawName);
|
||||
const formattedValue = numberFormatter(value as number);
|
||||
const formattedPercent = percentFormatter((percent as number) / 100);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import { TimeseriesDataRecord, NumberFormatter } from '@superset-ui/core';
|
||||
import { CallbackDataParams, OptionName } from 'echarts/types/src/util/types';
|
||||
import { TooltipMarker } from 'echarts/types/src/util/format';
|
||||
import { ForecastSeriesContext, ForecastSeriesEnum, ProphetValue } from '../types';
|
||||
import { sanitizeHtml } from './series';
|
||||
|
||||
const seriesTypeRegex = new RegExp(
|
||||
`(.+)(${ForecastSeriesEnum.ForecastLower}|${ForecastSeriesEnum.ForecastTrend}|${ForecastSeriesEnum.ForecastUpper})$`,
|
||||
@@ -73,7 +74,7 @@ export const formatProphetTooltipSeries = ({
|
||||
marker: TooltipMarker;
|
||||
formatter: NumberFormatter;
|
||||
}): string => {
|
||||
let row = `${marker}${seriesName}: `;
|
||||
let row = `${marker}${sanitizeHtml(seriesName)}: `;
|
||||
let isObservation = false;
|
||||
if (observation) {
|
||||
isObservation = true;
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
TimeFormatter,
|
||||
TimeseriesDataRecord,
|
||||
} from '@superset-ui/core';
|
||||
import { LegendComponentOption, SeriesOption } from 'echarts';
|
||||
import { format, LegendComponentOption, SeriesOption } from 'echarts';
|
||||
import { NULL_STRING, TIMESERIES_CONSTANTS } from '../constants';
|
||||
import { LegendOrientation, LegendType } from '../types';
|
||||
import { defaultLegendPadding } from '../defaults';
|
||||
@@ -200,3 +200,7 @@ export function dedupSeries(series: SeriesOption[]): SeriesOption[] {
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function sanitizeHtml(text: string): string {
|
||||
return format.encodeHTML(text);
|
||||
}
|
||||
|
||||
@@ -24,9 +24,11 @@ import {
|
||||
formatSeriesName,
|
||||
getChartPadding,
|
||||
getLegendProps,
|
||||
sanitizeHtml,
|
||||
} from '../../src/utils/series';
|
||||
import { LegendOrientation, LegendType } from '../../src/types';
|
||||
import { defaultLegendPadding } from '../../src/defaults';
|
||||
import { NULL_STRING } from '../../lib/constants';
|
||||
|
||||
describe('extractTimeseriesSeries', () => {
|
||||
it('should generate a valid ECharts timeseries series object', () => {
|
||||
@@ -350,4 +352,10 @@ describe('formatSeriesName', () => {
|
||||
).toEqual([{ id: 'foo' }, { id: 'bar' }, { id: 'foo (1)' }, { id: 'foo (2)' }]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sanitizeHtml', () => {
|
||||
it('should remove html tags from series name', () => {
|
||||
expect(sanitizeHtml(NULL_STRING)).toEqual('<NULL>');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user