Skip to content

HTML-safe aware String Escaping #603

@sandstrom

Description

@sandstrom

Background

Ember used to have a function escapeExpression (still in the code-base, but not public) living under String.escapeExpression.

During the move to module imports it wasn't ported (deliberately). However, htmlSafe and isHtmlSafe where ported.

Problem

If anyone wants to implement escapeExpression themselves, now that it isn't publicly available, they'll have to rely on private APIs of SafeString#toHTML (unless I've missed something obvious).

An implementation would look something like this:

import { isHTMLSafe } from '@ember/template';

const ESCAPE = {
  '&': '&',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#x27;',
  '`': '&#x60;',
  '=': '&#x3D;',
};

const BAD_CHARS = /[&<>"'`=]/g;
const POSSIBLE = /[&<>"'`=]/;

let escapeChar = function(chr) {
  return ESCAPE[chr];
};

// borrowed from Handlebars.utils.escapeexpression
// https://github.com/emberjs/ember.js/pull/18791
let escapeExpression = function(string) {
  if (typeof string !== 'string') {
    // don't escape SafeStrings, since they're already safe
    if (string && isHTMLSafe(string)) {
      return string.toHTML(); // private API, since SafeString isn't public
    } else if (string === null) {
      return '';
    } else if (!string) {
      return String(string);
    }

    // Force a string conversion as this will be done by the append regardless and
    // the regex test will do this transparently behind the scenes, causing issues if
    // an object's to string has escaped characters in it.
    string = String(string);
  }

  if (!POSSIBLE.test(string)) {
    return string;
  }

  return string.replace(BAD_CHARS, escapeChar);
};

Questions

  1. Have I missed something, or is this only possibly relying on the toHTML on SafeString, which is private?

  2. Is this by design or by accident?

Possible solutions

  • Make SafeString#toHTML public
  • Make escapeExpression public.
  • Let it slide, this probably isn't major issue for most people and can be handled in 'app land'.

I've also opened a PR that was closed. This is fine. But I'm opening this RFC issue since I'm not sure if it was closed knowing that private API must be relied on.

emberjs/ember.js#18791

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions