@lobehub/ui 2.24.0 → 2.24.1

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.
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
 
3
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
3
  var _excluded = ["animated", "fullFeatured", "actionIconSize", "children", "language", "className", "copyable", "showLanguage", "variant", "shadow", "wrap", "bodyRender", "actionsRender", "enableTransformer", "theme", "icon", "fileName", "allowChangeLanguage", "defaultExpand"];
5
4
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6
5
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
6
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
7
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
9
8
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
9
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
10
10
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
11
11
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
12
12
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -85,7 +85,16 @@ export var Highlighter = /*#__PURE__*/memo(function (_ref) {
85
85
  /* eslint-enable sort-keys-fix/sort-keys-fix */
86
86
  });
87
87
  }, [styles]);
88
- var tirmedChildren = children.trim();
88
+
89
+ // Safely handle children with boundary check
90
+ var tirmedChildren = useMemo(function () {
91
+ if (children === null || children === undefined) return '';
92
+ if (typeof children !== 'string') {
93
+ console.warn('Highlighter: children should be a string, received:', _typeof(children));
94
+ return String(children);
95
+ }
96
+ return children.trim();
97
+ }, [children]);
89
98
  var copyContentRef = useRef(tirmedChildren);
90
99
  useEffect(function () {
91
100
  copyContentRef.current = tirmedChildren;
@@ -3,6 +3,11 @@
3
3
  import { memo } from 'react';
4
4
  import { useHighlight } from "../../hooks/useHighlight";
5
5
  import { jsx as _jsx } from "react/jsx-runtime";
6
+ // Escape HTML for fallback to prevent XSS
7
+ var escapeHtml = function escapeHtml(str) {
8
+ return str.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&#039;');
9
+ };
10
+
6
11
  /**
7
12
  * Static renderer for syntax highlighting without animation
8
13
  * Uses useHighlight hook to generate HTML and renders it directly
@@ -15,7 +20,9 @@ var StaticRenderer = /*#__PURE__*/memo(function (_ref) {
15
20
  language = _ref.language,
16
21
  style = _ref.style,
17
22
  theme = _ref.theme;
18
- var _useHighlight = useHighlight(children, {
23
+ // Safely handle empty or invalid children
24
+ var safeChildren = children !== null && children !== void 0 ? children : '';
25
+ var _useHighlight = useHighlight(safeChildren, {
19
26
  enableTransformer: enableTransformer,
20
27
  language: language,
21
28
  theme: theme
@@ -26,7 +33,7 @@ var StaticRenderer = /*#__PURE__*/memo(function (_ref) {
26
33
  return /*#__PURE__*/_jsx("div", {
27
34
  className: containerClassName,
28
35
  dangerouslySetInnerHTML: {
29
- __html: data || "<pre><code>".concat(children, "</code></pre>")
36
+ __html: data || "<pre><code>".concat(escapeHtml(safeChildren), "</code></pre>")
30
37
  },
31
38
  dir: "ltr",
32
39
  style: style
@@ -97,7 +97,10 @@ var StreamRenderer = /*#__PURE__*/memo(function (_ref5) {
97
97
  theme = _ref5.theme;
98
98
  var _useStyles = useStyles(),
99
99
  cx = _useStyles.cx;
100
- var _useHighlight = useHighlight(children, {
100
+
101
+ // Safely handle empty or invalid children
102
+ var safeChildren = children !== null && children !== void 0 ? children : '';
103
+ var _useHighlight = useHighlight(safeChildren, {
101
104
  enableTransformer: enableTransformer,
102
105
  language: language,
103
106
  streaming: true,
@@ -114,7 +117,7 @@ var StreamRenderer = /*#__PURE__*/memo(function (_ref5) {
114
117
  style: style,
115
118
  children: /*#__PURE__*/_jsx("pre", {
116
119
  children: /*#__PURE__*/_jsx("code", {
117
- children: children
120
+ children: safeChildren
118
121
  })
119
122
  })
120
123
  });
@@ -102,13 +102,14 @@ var useStreamingHighlighter = function useStreamingHighlighter(text, options) {
102
102
  setResult = _useState2[1];
103
103
  var tokenizerRef = useRef(null);
104
104
  var previousTextRef = useRef('');
105
- var latestTextRef = useRef(text);
105
+ var safeText = text !== null && text !== void 0 ? text : '';
106
+ var latestTextRef = useRef(safeText);
106
107
  var preStyleRef = useRef(undefined);
107
108
  var colorReplacementsRef = useRef(colorReplacements);
108
109
  var linesRef = useRef([[]]);
109
110
  useEffect(function () {
110
- latestTextRef.current = text;
111
- }, [text]);
111
+ latestTextRef.current = safeText;
112
+ }, [safeText]);
112
113
  useEffect(function () {
113
114
  colorReplacementsRef.current = colorReplacements;
114
115
  }, [colorReplacements]);
@@ -281,8 +282,8 @@ var useStreamingHighlighter = function useStreamingHighlighter(text, options) {
281
282
  useEffect(function () {
282
283
  if (!enabled) return;
283
284
  if (!tokenizerRef.current) return;
284
- updateTokens(text);
285
- }, [enabled, text, updateTokens]);
285
+ updateTokens(safeText);
286
+ }, [enabled, safeText, updateTokens]);
286
287
  return result;
287
288
  };
288
289
 
@@ -295,7 +296,10 @@ export var useHighlight = function useHighlight(text, _ref3) {
295
296
  var _useThemeMode = useThemeMode(),
296
297
  isDarkMode = _useThemeMode.isDarkMode;
297
298
  var theme = useTheme();
298
- var lang = language.toLowerCase();
299
+
300
+ // Safely handle language and text with boundary checks
301
+ var safeText = text !== null && text !== void 0 ? text : '';
302
+ var lang = (language !== null && language !== void 0 ? language : 'plaintext').toLowerCase();
299
303
 
300
304
  // Match supported languages
301
305
  var matchedLanguage = useMemo(function () {
@@ -340,9 +344,9 @@ export var useHighlight = function useHighlight(text, _ref3) {
340
344
  // Build cache key
341
345
  var cacheKey = useMemo(function () {
342
346
  // Use hash for long text
343
- var hash = text.length < MD5_LENGTH_THRESHOLD ? text : Md5.hashStr(text);
347
+ var hash = safeText.length < MD5_LENGTH_THRESHOLD ? safeText : Md5.hashStr(safeText);
344
348
  return [matchedLanguage, builtinTheme || (isDarkMode ? 'd' : 'l'), hash].filter(Boolean).join('-');
345
- }, [text, matchedLanguage, isDarkMode, builtinTheme]);
349
+ }, [safeText, matchedLanguage, isDarkMode, builtinTheme]);
346
350
 
347
351
  // Use SWR to get highlighted HTML
348
352
  var response = useSWR(streaming ? null : cacheKey, /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
@@ -359,10 +363,10 @@ export var useHighlight = function useHighlight(text, _ref3) {
359
363
  _context3.next = 6;
360
364
  break;
361
365
  }
362
- return _context3.abrupt("return", text);
366
+ return _context3.abrupt("return", safeText);
363
367
  case 6:
364
368
  _context3.next = 8;
365
- return codeToHtml(text, {
369
+ return codeToHtml(safeText, {
366
370
  colorReplacements: builtinTheme ? undefined : colorReplacements,
367
371
  lang: matchedLanguage,
368
372
  theme: builtinTheme || (isDarkMode ? 'slack-dark' : 'slack-ochin'),
@@ -384,10 +388,10 @@ export var useHighlight = function useHighlight(text, _ref3) {
384
388
  _context3.next = 21;
385
389
  break;
386
390
  }
387
- return _context3.abrupt("return", text);
391
+ return _context3.abrupt("return", safeText);
388
392
  case 21:
389
393
  _context3.next = 23;
390
- return _codeToHtml(text, {
394
+ return _codeToHtml(safeText, {
391
395
  lang: matchedLanguage,
392
396
  theme: isDarkMode ? 'dark-plus' : 'light-plus'
393
397
  });
@@ -398,7 +402,7 @@ export var useHighlight = function useHighlight(text, _ref3) {
398
402
  _context3.prev = 27;
399
403
  _context3.t1 = _context3["catch"](15);
400
404
  // Fallback to plain text
401
- fallbackHtml = "<pre class=\"fallback\"><code>".concat(escapeHtml(text), "</code></pre>");
405
+ fallbackHtml = "<pre class=\"fallback\"><code>".concat(escapeHtml(safeText), "</code></pre>");
402
406
  return _context3.abrupt("return", fallbackHtml);
403
407
  case 31:
404
408
  case "end":
@@ -414,7 +418,7 @@ export var useHighlight = function useHighlight(text, _ref3) {
414
418
  revalidateOnReconnect: false
415
419
  });
416
420
  var effectiveTheme = builtinTheme || (isDarkMode ? 'slack-dark' : 'slack-ochin');
417
- var streamingResult = useStreamingHighlighter(text, {
421
+ var streamingResult = useStreamingHighlighter(safeText, {
418
422
  colorReplacements: builtinTheme ? undefined : colorReplacements[effectiveTheme],
419
423
  enabled: streaming,
420
424
  language: matchedLanguage,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/ui",
3
- "version": "2.24.0",
3
+ "version": "2.24.1",
4
4
  "description": "Lobe UI is an open-source UI component library for building AIGC web apps",
5
5
  "keywords": [
6
6
  "lobehub",