Skip to content

Commit

Permalink
fix(plugin-chart-echarts): sanitize series from html tags (#1126)
Browse files Browse the repository at this point in the history
* fix(plugin-chart-echarts): sanitize series from html tags

* use echarts html encoder
  • Loading branch information
villebro authored and zhaoyongjie committed Nov 26, 2021
1 parent c160a4a commit 895d9d3
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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)}`;
},
},
Expand Down Expand Up @@ -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])}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
getChartPadding,
getColtypesMapping,
getLegendProps,
sanitizeHtml,
} from '../utils/series';
import { defaultGrid, defaultTooltip } from '../defaults';

Expand All @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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})$`,
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -200,3 +200,7 @@ export function dedupSeries(series: SeriesOption[]): SeriesOption[] {
};
});
}

export function sanitizeHtml(text: string): string {
return format.encodeHTML(text);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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('&lt;NULL&gt;');
});
});
});

0 comments on commit 895d9d3

Please sign in to comment.