-1

Requirements:

  • I have to fetch a URL that contains a single quote.
  • I am required to call a function via; e.g. <a href="javascript:my_function('my_quote%27s.txt');">...</a>.

After a lot of hassle of trying to properly encode a single quote (%27) both Waterfox and Chrome both keep throwing errors. Chrome allowed me to see that the error was triggered because the browsers are taking it upon themselves to decode strings (when I have not programed them to) turning %27 in to the literal single quote character so it errors out before the function is even called (e.g. my_function('my_quotes's.txt') with the quote being internally decoded and causing the obvious triple quote issue).

I could use PHP's htmlentities($file_name, ENT_QUOTES) though I'd have to string replace &#039; which seems pointlessly convoluted.

  • I am required to support the single quote and make the call via javascript:.
  • I'd like to avoid literal interpretation of encoded strings when calling functions.
  • I'd like to minimize the fuss and just use an encoding that JavaScript won't complain about.
  • No frameworks or libraries.

How do I properly encode a single quote in a manner that JavaScript won't take it upon itself to somehow internally decode it and throw errors?

John
  • 1
  • 13
  • 98
  • 177
  • 3
    "*I am required to make the call via `javascript:`*" - shudder. Don't. [It's known as a bad practice since over ten years!](https://stackoverflow.com/questions/2479557/why-is-it-bad-practice-to-use-links-with-the-javascript-protocol) And it's exactly what's causing the URL decoding of your script. – Bergi Dec 15 '20 at 21:24
  • Are you using PHP to generate this html? If you want to use PHP for encoding/escaping the value, please tag your question with it. – Bergi Dec 15 '20 at 21:26

2 Answers2

2

The value of an href a attribute is a URL. A javascript: scheme URL is a URL.

If you want a % to mean “A percent sign” instead of “The start of a percent encoded character” in a URL then you need to URL encode it.

...my_quote%2527s.txt...
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • A quick test reveals that your answer works. So how do I turn `%27` in to `%2527` via PHP? – John Dec 15 '20 at 21:23
  • I suspect `urlencode` will do it, but I’m not in a position to check. – Quentin Dec 15 '20 at 21:25
  • `rawurlencode(rawurlencode("'"))` does the trick...a little obnoxious though I'll get it ironed out. Thank you! I'll accept once the timer expires. – John Dec 15 '20 at 21:26
  • 1
    @John But that's most likely wrong. You need to js-escape the string literal. – Bergi Dec 15 '20 at 21:27
2

I am required to make the call via javascript:

Shudder. Please fix this. It's known as a bad practice since over ten years! And it's exactly what's causing the URI decoding - the javascript: schema is followed by an percent-encoded value to interpret.

So if you start with the js code

my_function('my&quote's.txt');

it would become one of

javascript:my_function%28%27my%26quote%27s.txt%27%29%3B
javascript:my_function(%27my%26quote%27s.txt%27)%3B
javascript:my_function('my%26quote's.txt')%3B

(the apostrophe ' and the parenthesis actually don't need to be encoded).

But 'my_quote's.txt' is not the valid javascript that you want to start with. What you're actually looking for is 'my_quote\'s.txt' or "my_quote's.txt'. To use these in a javascript:-scheme URI, it becomes

javascript:my_function('my_quote\'s.txt')%3B
javascript:my_function("my_quote's.txt")%3B

So if you generate this href string from a dynamic filename value, you must

  1. String-escape the filename in the JS string literal
  2. URL-encode the complete code in the javascript url
  3. html-entity-escape the complete href attribute value
Bergi
  • 630,263
  • 148
  • 957
  • 1,375