Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Fix browser crashing when searching for a malformed HTML tag #6297

Merged
merged 5 commits into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/HtmlUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { tryTransformPermalinkToLocalHref } from "./utils/permalinks/Permalinks"
import { SHORTCODE_TO_EMOJI, getEmojiFromUnicode } from "./emoji";
import ReplyThread from "./components/views/elements/ReplyThread";
import { mediaFromMxc } from "./customisations/Media";
import { highlight } from 'highlight.js';
germain-gg marked this conversation as resolved.
Show resolved Hide resolved

linkifyMatrix(linkify);

Expand Down Expand Up @@ -403,9 +404,11 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
try {
if (highlights && highlights.length > 0) {
const highlighter = new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink);
const safeHighlights = highlights.map(function(highlight) {
return sanitizeHtml(highlight, sanitizeParams);
});
const safeHighlights = highlights
// sanitizeHtml can hang if an unclosed HTML tag is thrown at it
// A search for `<foo` will make the browser crash
.filter((highlight: string): boolean => !highlight.includes("<"))
.map((highlight: string): string => sanitizeHtml(highlight, sanitizeParams));
germain-gg marked this conversation as resolved.
Show resolved Hide resolved
// XXX: hacky bodge to temporarily apply a textFilter to the sanitizeParams structure.
sanitizeParams.textFilter = function(safeText) {
return highlighter.applyHighlights(safeText, safeHighlights).join('');
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/rooms/EventTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ interface IProps {
showReactions?: boolean;

// which layout to use
layout: Layout;
layout?: Layout;
germain-gg marked this conversation as resolved.
Show resolved Hide resolved

// whether or not to show flair at all
enableFlair?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,27 @@ limitations under the License.
*/

import React from 'react';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import { haveTileForEvent } from "./EventTile";
import EventTile, { haveTileForEvent } from "./EventTile";
import DateSeparator from '../messages/DateSeparator';
import SettingsStore from "../../../settings/SettingsStore";
import { UIFeature } from "../../../settings/UIFeature";
import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks';
import { replaceableComponent } from "../../../utils/replaceableComponent";

@replaceableComponent("views.rooms.SearchResultTile")
export default class SearchResultTile extends React.Component {
static propTypes = {
// a matrix-js-sdk SearchResult containing the details of this result
searchResult: PropTypes.object.isRequired,

// a list of strings to be highlighted in the results
searchHighlights: PropTypes.array,

// href for the highlights in this result
resultLink: PropTypes.string,

onHeightChanged: PropTypes.func,
};
interface IProps {
// a matrix-js-sdk SearchResult containing the details of this result
searchResult: any;
germain-gg marked this conversation as resolved.
Show resolved Hide resolved
// a list of strings to be highlighted in the results
searchHighlights?: string[];
// href for the highlights in this result
resultLink?: string;
onHeightChanged?: () => void;
permalinkCreator?: RoomPermalinkCreator;
}

render() {
const DateSeparator = sdk.getComponent('messages.DateSeparator');
const EventTile = sdk.getComponent('rooms.EventTile');
@replaceableComponent("views.rooms.SearchResultTile")
export default class SearchResultTile extends React.Component<IProps> {
public render() {
const result = this.props.searchResult;
const mxEv = result.context.getEvent();
const eventId = mxEv.getId();
Expand Down