Repository: mermaid-js/mermaid
File: packages/mermaid/src/diagrams/common/common.ts (TypeScript)

Code before:
 *
 * @param s - HTML string
 * @returns String with placeholders
 */
const breakToPlaceholder = (s: string): string => {
  return s.replace(lineBreakRegex, '#br#');
};

/**
 * Gets the current URL
 *
 * @param useAbsolute - Whether to return the absolute URL or not
 * @returns The current URL
 */
const getUrl = (useAbsolute: boolean): string => {
  let url = '';
  if (useAbsolute) {
    url =
      window.location.protocol +
      '//' +
      window.location.host +
      window.location.pathname +
      window.location.search;
    url = url.replace(/\\/g, '\\\\');
    url = url.replaceAll(/\(/g, '\\(');
    url = url.replaceAll(/\)/g, '\\)');
  }

  return url;
};

/**
 * Converts a string/boolean into a boolean
 *
 * @param val - String or boolean to convert
 * @returns The result from the input
 */
export const evaluate = (val?: string | boolean): boolean =>
  val === false || ['false', 'null', '0'].includes(String(val).trim().toLowerCase()) ? false : true;

/**
 * Wrapper around Math.max which removes non-numeric values
 * Returns the larger of a set of supplied numeric expressions.
 * @param values - Numeric expressions to be evaluated
 * @returns The smaller value
 */
export const getMax = function (...values: number[]): number {
  const newValues: number[] = values.filter((value) => {
    return !isNaN(value);
  });
  return Math.max(...newValues);

Review comment (security):
I think instead of using `url = url.replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)');`, we might want to use [`CSS.escape()`](https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape_static).

It looks like we're trying to create valid [`CSS <url-token>`](https://www.w3.org/TR/css-syntax-3/#typedef-url-token), as these are passed unquoted to the [SVG/CSS `url()` function](https://developer.mozilla.org/en-US/docs/Web/CSS/url_function). `CSS.escape` will probably overly escape characters, but it's probably cleaner and describes what we want to do better.

There's other characters that are valid in a URI like `'`, but aren't valid in a CSS `<url-token>` so they should be escaped too.

Code after:
 *
 * @param s - HTML string
 * @returns String with placeholders
 */
const breakToPlaceholder = (s: string): string => {
  return s.replace(lineBreakRegex, '#br#');
};

/**
 * Gets the current URL
 *
 * @param useAbsolute - Whether to return the absolute URL or not
 * @returns The current URL
 */
export const getUrl = (useAbsolute: boolean): string => {
  let url = '';
  if (useAbsolute) {
    url =
      window.location.protocol +
      '//' +
      window.location.host +
      window.location.pathname +
      window.location.search;

    url = CSS.escape(url);
  }

  return url;
};

/**
 * Converts a string/boolean into a boolean
 *
 * @param val - String or boolean to convert
 * @returns The result from the input
 */
export const evaluate = (val?: string | boolean): boolean =>
  val === false || ['false', 'null', '0'].includes(String(val).trim().toLowerCase()) ? false : true;

/**
 * Wrapper around Math.max which removes non-numeric values
 * Returns the larger of a set of supplied numeric expressions.
 * @param values - Numeric expressions to be evaluated
 * @returns The smaller value
 */
export const getMax = function (...values: number[]): number {
  const newValues: number[] = values.filter((value) => {
    return !isNaN(value);
  });
  return Math.max(...newValues);
};