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

View file

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

View file

@ -19,7 +19,7 @@ import {
restoreScrollPosition,
saveScrollPosition,
} from "@utils/browser";
import { debounce, randomStr, unescapeHTML } from "@utils/helpers";
import { debounce, randomStr } from "@utils/helpers";
import { isImage } from "@utils/media";
import { RouteDataResponse } from "@utils/types";
import autosize from "autosize";
@ -325,9 +325,8 @@ export class Post extends Component<any, PostState> {
get documentTitle(): string {
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"
? `${postTitle} - ${siteName}`
? `${this.state.postRes.data.post_view.post.name} - ${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 randomStr from "./random-str";
import removeAuthParam from "./remove-auth-param";
import returnStringFromString from "./return-str";
import sleep from "./sleep";
import validEmail from "./valid-email";
import validInstanceTLD from "./valid-instance-tld";
import validTitle from "./valid-title";
import validURL from "./valid-url";
import { escapeHTML, unescapeHTML } from "./html-entities";
export {
capitalizeFirstLetter,
debounce,
editListImmutable,
escapeHTML,
formatPastDate,
futureDaysToUnixTime,
getIdFromString,
@ -48,9 +45,7 @@ export {
poll,
randomStr,
removeAuthParam,
returnStringFromString,
sleep,
unescapeHTML,
validEmail,
validInstanceTLD,
validTitle,