You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by jo...@apache.org on 2023/03/13 19:11:23 UTC
[superset] branch master updated: fix(dashboard): deepmerge htmlSchemaOverrides (#23329)
This is an automated email from the ASF dual-hosted git repository.
johnbodley pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 3919ca6060 fix(dashboard): deepmerge htmlSchemaOverrides (#23329)
3919ca6060 is described below
commit 3919ca60608e1c2d3cfef99d5a8d9d2aef227843
Author: JUST.in DO IT <ju...@airbnb.com>
AuthorDate: Mon Mar 13 12:11:12 2023 -0700
fix(dashboard): deepmerge htmlSchemaOverrides (#23329)
---
.../src/components/SafeMarkdown.tsx | 16 +++++++--
.../test/components/SafeMarkdown.test.ts | 39 ++++++++++++++++++++++
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/superset-frontend/packages/superset-ui-core/src/components/SafeMarkdown.tsx b/superset-frontend/packages/superset-ui-core/src/components/SafeMarkdown.tsx
index 4db48d4265..8be73295b4 100644
--- a/superset-frontend/packages/superset-ui-core/src/components/SafeMarkdown.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/components/SafeMarkdown.tsx
@@ -20,7 +20,7 @@ import React, { useMemo } from 'react';
import ReactMarkdown from 'react-markdown';
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
import rehypeRaw from 'rehype-raw';
-import { merge } from 'lodash';
+import { mergeWith, isArray } from 'lodash';
import { FeatureFlag, isFeatureEnabled } from '../utils';
interface SafeMarkdownProps {
@@ -29,6 +29,15 @@ interface SafeMarkdownProps {
htmlSchemaOverrides?: typeof defaultSchema;
}
+export function getOverrideHtmlSchema(
+ originalSchema: typeof defaultSchema,
+ htmlSchemaOverrides: SafeMarkdownProps['htmlSchemaOverrides'],
+) {
+ return mergeWith(originalSchema, htmlSchemaOverrides, (objValue, srcValue) =>
+ isArray(objValue) ? objValue.concat(srcValue) : undefined,
+ );
+}
+
function SafeMarkdown({
source,
htmlSanitization = true,
@@ -42,7 +51,10 @@ function SafeMarkdown({
if (displayHtml && !escapeHtml) {
rehypePlugins.push(rehypeRaw);
if (htmlSanitization) {
- const schema = merge(defaultSchema, htmlSchemaOverrides);
+ const schema = getOverrideHtmlSchema(
+ defaultSchema,
+ htmlSchemaOverrides,
+ );
rehypePlugins.push([rehypeSanitize, schema]);
}
}
diff --git a/superset-frontend/packages/superset-ui-core/test/components/SafeMarkdown.test.ts b/superset-frontend/packages/superset-ui-core/test/components/SafeMarkdown.test.ts
new file mode 100644
index 0000000000..4b4c826923
--- /dev/null
+++ b/superset-frontend/packages/superset-ui-core/test/components/SafeMarkdown.test.ts
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { getOverrideHtmlSchema } from '../../src/components/SafeMarkdown';
+
+describe('getOverrideHtmlSchema', () => {
+ it('should append the override items', () => {
+ const original = {
+ attributes: {
+ '*': ['size'],
+ },
+ clobberPrefix: 'original-prefix',
+ tagNames: ['h1', 'h2', 'h3'],
+ };
+ const result = getOverrideHtmlSchema(original, {
+ attributes: { '*': ['src'], h1: ['style'] },
+ clobberPrefix: 'custom-prefix',
+ tagNames: ['iframe'],
+ });
+ expect(result.clobberPrefix).toEqual('custom-prefix');
+ expect(result.attributes).toEqual({ '*': ['size', 'src'], h1: ['style'] });
+ expect(result.tagNames).toEqual(['h1', 'h2', 'h3', 'iframe']);
+ });
+});