@ecency/render-helper 2.5.4 → 2.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -93,14 +93,14 @@ var INTERNAL_POST_TAG_REGEX = /^(.+?)\/(@[\w.\d-]+)\/(.*)$/i;
93
93
  var INTERNAL_POST_REGEX = /^\/(@[\w.\d-]+)\/(.*)$/i;
94
94
  var CUSTOM_COMMUNITY_REGEX = /^https?:\/\/(.*)\/c\/(hive-\d+)(.*)/i;
95
95
  var YOUTUBE_REGEX = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|shorts\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i;
96
- var YOUTUBE_EMBED_REGEX = /^(https?:)?\/\/www.youtube.com\/(embed|shorts)\/.*/i;
96
+ var YOUTUBE_EMBED_REGEX = /^(https?:)?\/\/www\.youtube\.com\/(embed|shorts)\/.*/i;
97
97
  var VIMEO_REGEX = /(https?:\/\/)?(www\.)?(?:vimeo)\.com.*(?:videos|video|channels|)\/([\d]+)/i;
98
98
  var VIMEO_EMBED_REGEX = /https:\/\/player\.vimeo\.com\/video\/([0-9]+)(?:$|[?#])/;
99
- var BITCHUTE_REGEX = /^(?:https?:\/\/)?(?:www\.)?bitchute.com\/(?:video|embed)\/([a-z0-9]+)/i;
99
+ var BITCHUTE_REGEX = /^(?:https?:\/\/)?(?:www\.)?bitchute\.com\/(?:video|embed)\/([a-z0-9]+)/i;
100
100
  var D_TUBE_REGEX = /(https?:\/\/d\.tube\/#!\/v\/)(\w+)\/(\w+)/g;
101
101
  var D_TUBE_REGEX2 = /(https?:\/\/d\.tube\/v\/)(\w+)\/(\w+)/g;
102
102
  var D_TUBE_EMBED_REGEX = /^https:\/\/emb.d.tube\/#!\/[^/?#]+\/[^/?#]+(?:$|[?#])/i;
103
- var TWITCH_REGEX = /https?:\/\/(?:www.)?twitch.tv\/(?:(videos)\/)?([a-zA-Z0-9][\w]{3,24})/i;
103
+ var TWITCH_REGEX = /https?:\/\/(?:www\.)?twitch\.tv\/(?:(videos)\/)?([a-zA-Z0-9][\w]{3,24})/i;
104
104
  var DAPPLR_REGEX = /^(https?:)?\/\/[a-z]*\.dapplr.in\/file\/dapplr-videos\/.*/i;
105
105
  var TRUVVL_REGEX = /^https?:\/\/embed.truvvl.com\/(@[\w.\d-]+)\/(.*)/i;
106
106
  var LBRY_REGEX = /^(https?:)?\/\/lbry.tv\/\$\/embed\/[^?#]+(?:$|[?#])/i;
@@ -113,15 +113,15 @@ var SPEAK_AUDIO_REGEX = /https?:\/\/audio\.3speak\.tv\/play\?[^\s]+/i;
113
113
  var SPEAK_AUDIO_EMBED_REGEX = /^https?:\/\/audio\.3speak\.tv\/play\?.+$/i;
114
114
  var TWITTER_REGEX = /(?:https?:\/\/(?:(?:twitter\.com\/(.*?)\/status\/(.*))))/gi;
115
115
  var SPOTIFY_REGEX = /^https:\/\/open\.spotify\.com\/playlist\/(.*)?$/gi;
116
- var RUMBLE_REGEX = /^https:\/\/rumble.com\/embed\/([a-zA-Z0-9-]+)\/\?pub=\w+/;
116
+ var RUMBLE_REGEX = /^https:\/\/rumble\.com\/embed\/([a-zA-Z0-9-]+)\/\?pub=\w+/;
117
117
  var BRIGHTEON_REGEX = /^https?:\/\/(www\.)?brighteon\.com\/(?:embed\/)?(.*[0-9].*)/i;
118
- var VIMM_EMBED_REGEX = /^https:\/\/www.vimm.tv\/[^?#]+(?:$|[?#])/i;
118
+ var VIMM_EMBED_REGEX = /^https:\/\/www\.vimm\.tv\/[^?#]+(?:$|[?#])/i;
119
119
  var SPOTIFY_EMBED_REGEX = /^https:\/\/open\.spotify\.com\/(embed|embed-podcast)\/(playlist|show|episode|track|album)\/([^/?#]+)(?:$|[?#])/i;
120
- var SOUNDCLOUD_EMBED_REGEX = /^https:\/\/w.soundcloud.com\/player\/\?[^#]+$/i;
121
- var TWITCH_EMBED_REGEX = /^(https?:)?\/\/player.twitch.tv\/(?:\?[^/]+)?$/i;
120
+ var SOUNDCLOUD_EMBED_REGEX = /^https:\/\/w\.soundcloud\.com\/player\/\?[^#]+$/i;
121
+ var TWITCH_EMBED_REGEX = /^(https?:)?\/\/player\.twitch\.tv\/(?:\?[^/]+)?$/i;
122
122
  var BRAND_NEW_TUBE_REGEX = /^https:\/\/brandnewtube\.com\/embed\/[a-z0-9]+$/i;
123
- var LOOM_REGEX = /^(https?:)?\/\/www.loom.com\/share\/([^/?#]+)(?:$|[?#])/i;
124
- var LOOM_EMBED_REGEX = /^(https?:)?\/\/www.loom.com\/embed\/([^/?#]+)(?:$|[?#])/i;
123
+ var LOOM_REGEX = /^(https?:)?\/\/www\.loom\.com\/share\/([^/?#]+)(?:$|[?#])/i;
124
+ var LOOM_EMBED_REGEX = /^(https?:)?\/\/www\.loom\.com\/embed\/([^/?#]+)(?:$|[?#])/i;
125
125
  var AUREAL_EMBED_REGEX = /^(https?:)?\/\/(www\.)?(?:aureal-embed)\.web\.app\/([0-9]+)(?:$|[?#])/i;
126
126
  var ENTITY_REGEX = /&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-fA-F]{1,6});/ig;
127
127
  var SECTION_REGEX = /\B(\#[\da-zA-Z-_]+\b)(?!;)/i;
@@ -473,12 +473,12 @@ function sanitizeHtml(html) {
473
473
  const decoded = decodeEntities(value.trim());
474
474
  const decodedLower = decoded.toLowerCase();
475
475
  if (name.startsWith("on")) return "";
476
- if (tag === "img" && name === "src" && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
476
+ if (tag === "img" && name === "src" && !/^https?:\/\//.test(decodedLower)) return "";
477
477
  if (tag === "img" && name === "srcset") {
478
478
  const candidates = decoded.split(",").map((c) => c.trim().split(/\s+/)[0]);
479
- if (candidates.some((url) => !/^https?:\/\//.test(url))) return "";
479
+ if (candidates.some((url) => !/^https?:\/\//i.test(url))) return "";
480
480
  }
481
- if (tag === "video" && ["src", "poster"].includes(name) && (!/^https?:\/\//.test(decodedLower) || decodedLower.startsWith("javascript:"))) return "";
481
+ if (tag === "video" && ["src", "poster"].includes(name) && !/^https?:\/\//.test(decodedLower)) return "";
482
482
  if (tag === "img" && ["dynsrc", "lowsrc"].includes(name)) return "";
483
483
  if (tag === "span" && name === "class" && decoded.toLowerCase().trim() === "wr") return "";
484
484
  if (name === "id") {
@@ -556,11 +556,11 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
556
556
  var SRCSET_WIDTHS = [320, 600, 800, 1024, 1280];
557
557
  function buildSrcSet(url) {
558
558
  if (!url || typeof url !== "string") return "";
559
- const escapedBase = proxyBase.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
560
- const proxyPattern = new RegExp(`^${escapedBase}/p/([^?]+)`);
561
- const match = url.match(proxyPattern);
562
- if (match) {
563
- const phash = extractPHash(url) || match[1];
559
+ const proxyPrefix = `${proxyBase}/p/`;
560
+ if (url.startsWith(proxyPrefix)) {
561
+ const rest = url.slice(proxyPrefix.length);
562
+ const q = rest.indexOf("?");
563
+ const phash = extractPHash(url) || (q >= 0 ? rest.slice(0, q) : rest);
564
564
  return SRCSET_WIDTHS.map((w) => `${proxyBase}/p/${phash}?format=match&mode=fit&width=${w} ${w}w`).join(", ");
565
565
  }
566
566
  return SRCSET_WIDTHS.map((w) => {
@@ -699,7 +699,10 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
699
699
  if (className && (["markdown-author-link", "markdown-tag-link"].includes(className) || className.includes("er-author") || className.includes("er-tag"))) {
700
700
  return;
701
701
  }
702
- if (href && href.trim().toLowerCase().startsWith("javascript:")) {
702
+ const trimmed = href.trim().replace(/[\t\n\r\f\v\0]/g, "").toLowerCase();
703
+ const isSafeScheme = /^(https?|mailto|hive|tel|web\+[a-z0-9.+-]+):/i.test(trimmed);
704
+ const isRelative = /^(\/\/|\/[^/]?|#|\?|[a-z0-9._\-]+(\/|$))/i.test(trimmed);
705
+ if (!isSafeScheme && !isRelative) {
703
706
  el.removeAttribute("href");
704
707
  return;
705
708
  }
@@ -1474,7 +1477,7 @@ function linkify(content, forApp, renderOptions) {
1474
1477
  content = content.replace(/(^|\s|>)(#[-a-z\d]+)/gi, (tag) => {
1475
1478
  if (/#[\d]+$/.test(tag)) return tag;
1476
1479
  const preceding = /^\s|>/.test(tag) ? tag[0] : "";
1477
- tag = tag.replace(">", "");
1480
+ tag = tag.replace(/^>/, "");
1478
1481
  const tag2 = tag.trim().substring(1);
1479
1482
  const tagLower = tag2.toLowerCase();
1480
1483
  if (!forApp) {