Revert "Improve handling/escaping of a few possible html entities for posts titles (&) - does not fix backend, only frontend display (#2087)"

This reverts commit 8977b5353a.
This commit is contained in:
Dessalines 2023-09-29 07:43:34 -04:00
parent 8660a788bf
commit f4172b42b8
5 changed files with 18 additions and 92 deletions

View file

@ -1,7 +1,6 @@
import { Component } from "inferno"; import { Component } from "inferno";
import { Post } from "lemmy-js-client"; import { Post } from "lemmy-js-client";
import * as sanitizeHtml from "sanitize-html"; import * as sanitizeHtml from "sanitize-html";
import { unescapeHTML } from "@utils/helpers";
import { relTags } from "../../config"; import { relTags } from "../../config";
import { Icon } from "../common/icon"; import { Icon } from "../common/icon";
@ -26,21 +25,17 @@ export class MetadataCard extends Component<MetadataCardProps> {
{post.name !== post.embed_title && ( {post.name !== post.embed_title && (
<> <>
<h5 className="card-title d-inline"> <h5 className="card-title d-inline">
<a <a className="text-body" href={post.url} rel={relTags}>
className="text-body" {post.embed_title}
href={unescapeHTML(post.url)}
rel={relTags}
>
{unescapeHTML(post.embed_title)}
</a> </a>
</h5> </h5>
<span className="d-inline-block ms-2 mb-2 small text-muted"> <span className="d-inline-block ms-2 mb-2 small text-muted">
<a <a
className="text-muted fst-italic" className="text-muted fst-italic"
href={unescapeHTML(post.url)} href={post.url}
rel={relTags} rel={relTags}
> >
{new URL(unescapeHTML(post.url)).hostname} {new URL(post.url).hostname}
<Icon icon="external-link" classes="ms-1" /> <Icon icon="external-link" classes="ms-1" />
</a> </a>
</span> </span>

View file

@ -5,7 +5,6 @@ import {
capitalizeFirstLetter, capitalizeFirstLetter,
futureDaysToUnixTime, futureDaysToUnixTime,
hostname, hostname,
unescapeHTML,
} from "@utils/helpers"; } from "@utils/helpers";
import { isImage, isVideo } from "@utils/media"; import { isImage, isVideo } from "@utils/media";
import { import {
@ -207,9 +206,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<> <>
{this.listing()} {this.listing()}
{this.state.imageExpanded && !this.props.hideImage && this.img} {this.state.imageExpanded && !this.props.hideImage && this.img}
{this.showBody && {this.showBody && post.url && post.embed_title && (
unescapeHTML(post.url) && <MetadataCard post={post} />
unescapeHTML(post.embed_title) && <MetadataCard post={post} />} )}
{this.showBody && this.body()} {this.showBody && this.body()}
</> </>
) : ( ) : (
@ -286,8 +285,8 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
<iframe <iframe
allowFullScreen allowFullScreen
className="post-metadata-iframe" className="post-metadata-iframe"
src={unescapeHTML(post.embed_video_url)} src={post.embed_video_url}
title={unescapeHTML(post.embed_title)} title={post.embed_title}
></iframe> ></iframe>
</div> </div>
); );
@ -310,7 +309,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
get imageSrc(): string | undefined { get imageSrc(): string | undefined {
const post = this.postView.post; const post = this.postView.post;
const url = unescapeHTML(post.url); const url = post.url;
const thumbnail = post.thumbnail_url; const thumbnail = post.thumbnail_url;
if (thumbnail) { if (thumbnail) {
@ -324,7 +323,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
thumbnail() { thumbnail() {
const post = this.postView.post; const post = this.postView.post;
const url = unescapeHTML(post.url); const url = post.url;
const thumbnail = post.thumbnail_url; const thumbnail = post.thumbnail_url;
if (!this.props.hideImage && url && isImage(url) && this.imageSrc) { if (!this.props.hideImage && url && isImage(url) && this.imageSrc) {
@ -450,7 +449,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
> >
<span <span
className="d-inline" className="d-inline"
dangerouslySetInnerHTML={mdToHtmlInline(unescapeHTML(post.name))} dangerouslySetInnerHTML={mdToHtmlInline(post.name)}
/> />
</Link> </Link>
); );
@ -458,7 +457,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
postTitleLine() { postTitleLine() {
const post = this.postView.post; const post = this.postView.post;
const url = unescapeHTML(post.url); const url = post.url;
return ( return (
<> <>
@ -474,9 +473,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
href={url} href={url}
title={url} title={url}
rel={relTags} rel={relTags}
dangerouslySetInnerHTML={mdToHtmlInline( dangerouslySetInnerHTML={mdToHtmlInline(post.name)}
unescapeHTML(post.name),
)}
></a> ></a>
) : ( ) : (
this.postLink this.postLink
@ -489,7 +486,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
* MetadataCard/body toggle. * MetadataCard/body toggle.
*/} */}
{!this.props.showBody && {!this.props.showBody &&
(unescapeHTML(post.url && post.embed_title) || post.body) && ((post.url && post.embed_title) || post.body) &&
this.showPreviewButton()} this.showPreviewButton()}
{post.removed && ( {post.removed && (
@ -551,7 +548,7 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
urlLine() { urlLine() {
const post = this.postView.post; const post = this.postView.post;
const url = unescapeHTML(post.url); const url = post.url;
return ( return (
<p className="small m-0"> <p className="small m-0">

View file

@ -19,7 +19,7 @@ import {
restoreScrollPosition, restoreScrollPosition,
saveScrollPosition, saveScrollPosition,
} from "@utils/browser"; } from "@utils/browser";
import { debounce, randomStr, unescapeHTML } from "@utils/helpers"; import { debounce, randomStr } from "@utils/helpers";
import { isImage } from "@utils/media"; import { isImage } from "@utils/media";
import { RouteDataResponse } from "@utils/types"; import { RouteDataResponse } from "@utils/types";
import autosize from "autosize"; import autosize from "autosize";
@ -325,9 +325,8 @@ export class Post extends Component<any, PostState> {
get documentTitle(): string { get documentTitle(): string {
const siteName = this.state.siteRes.site_view.site.name; const siteName = this.state.siteRes.site_view.site.name;
const postTitle = unescapeHTML(this.state.postRes.data.post_view.post.name);
return this.state.postRes.state === "success" return this.state.postRes.state === "success"
? `${postTitle} - ${siteName}` ? `${this.state.postRes.data.post_view.post.name} - ${siteName}`
: siteName; : siteName;
} }

View file

@ -1,60 +0,0 @@
const matchEscHtmlRx = /["'&<>]/;
const matchUnEscRx = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
export function escapeHTML(str: string): string {
const matchEscHtml = matchEscHtmlRx.exec(str);
if (!matchEscHtml) {
return str;
}
let escape;
let html = "";
let index = 0;
let lastIndex = 0;
for (index = matchEscHtml.index; index < str.length; index++) {
switch (str.charCodeAt(index)) {
case 34: // "
escape = "&quot;";
break;
case 38: // &
escape = "&amp;";
break;
case 39: // '
escape = "&#39;";
break;
case 60: // <
escape = "&lt;";
break;
case 62: // >
escape = "&gt;";
break;
default:
continue;
}
if (lastIndex !== index) {
html += str.substring(lastIndex, index);
}
lastIndex = index + 1;
html += escape;
}
return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
}
export function unescapeHTML(str: string): string {
const matchUnEsc = matchUnEscRx.exec(str);
if (!matchUnEsc) {
return str;
}
const res = str
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'")
.replace(/&#x3A;/g, ":")
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&amp;/g, "&");
return unescapeHTML(res);
}

View file

@ -18,19 +18,16 @@ import numToSI from "./num-to-si";
import poll from "./poll"; import poll from "./poll";
import randomStr from "./random-str"; import randomStr from "./random-str";
import removeAuthParam from "./remove-auth-param"; import removeAuthParam from "./remove-auth-param";
import returnStringFromString from "./return-str";
import sleep from "./sleep"; import sleep from "./sleep";
import validEmail from "./valid-email"; import validEmail from "./valid-email";
import validInstanceTLD from "./valid-instance-tld"; import validInstanceTLD from "./valid-instance-tld";
import validTitle from "./valid-title"; import validTitle from "./valid-title";
import validURL from "./valid-url"; import validURL from "./valid-url";
import { escapeHTML, unescapeHTML } from "./html-entities";
export { export {
capitalizeFirstLetter, capitalizeFirstLetter,
debounce, debounce,
editListImmutable, editListImmutable,
escapeHTML,
formatPastDate, formatPastDate,
futureDaysToUnixTime, futureDaysToUnixTime,
getIdFromString, getIdFromString,
@ -48,9 +45,7 @@ export {
poll, poll,
randomStr, randomStr,
removeAuthParam, removeAuthParam,
returnStringFromString,
sleep, sleep,
unescapeHTML,
validEmail, validEmail,
validInstanceTLD, validInstanceTLD,
validTitle, validTitle,