1

I'm writing code that will generate some javascript. The javascript will involve assigning a variable in the generated code to a string passed into the generator. The generator is also in javascript.

Basically I want to do this:

function generate_code(text) {
    return "var a = " + jsEscapeString(text) + "; alert(a);";
}
function jsEscapeString(text) {
    // WHAT GOES HERE?
    // e.g. it needs to:
    // - surround with quotes
    // - escape quotes inside the text
    // - escape backslashes and newlines and other fun characters
    // - defend against other horrible things I probably don't know about
}

I don't want something that only works in the happy case. I want something correct. Something that would survive a malicious adversary trying to do sandbox escapes on the resulting code (e.g. like what you do in the game 'Untrusted').

1
  • 1
    (This question is probably a duplicate, but my google-fu is failing me.) Commented Sep 20, 2015 at 23:36

2 Answers 2

4

Super easy.

function jsEscapeString(text) {
    return JSON.stringify(text);
}

No matter what you put in, you will ALWAYS get a valid representation of it that can be dumped into JS source. The result, when executed, will always be exactly what you put in.

This even works for strings, booleans, numbers, arrays, objects... basically everything you'll ever need.

Although I'm curious as to why you're doing this... This smells of eval fishiness...

Sign up to request clarification or add additional context in comments.

1 Comment

Ah, of course. (It's for a widget where users can enter javascript as part of solving a puzzle. It's not security sensitive or affecting data that matters, I just didn't want to write it in a way that would break as soon as they included a quote.)
-1

You would need to escape backslash, the string delimiter, and control characters:

function jsEscapeString(text) {
  return '"' +
    text
    .replace(/\\/g, '\\\\')
    .replace(/"/g, '\\"')
    .replace(/\r/g, '\\r')
    .replace(/\n/g, '\\n')
    .replace(/\t/g, '\\t')
    .replace(/\b/g, '\\b')
    .replace(/\v/g, '\\v')
    .replace(/\f/g, '\\f')
    + '"';
}

4 Comments

There's no unicode characters that can break strings, such as alternative characters for starting a new line?
@Strilanc: No, there is no purpose for other new line characters, and other character have no special meaning. Unicode has alternative quotation marks for example, but JavaScript doesn't allow those as string delimiters.
It is extremely useless to escape \r\n\t\b\v\f in generated code. Yes, the result may not look desirable, but more often than not the effort is wasted.
@AnrDaemon: Why do you think that it is "extremely useless" when it makes the difference between the code not working and the code working? Why do you think that this way of escaping characters are useless, but using JSON.stringify is not, when they do essentially the same thing?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.