1

I am facing an issue regarding decoding special characters, specifically the ampersand (&) character.

SETUP

Frontend: Angular-6/Typescript

Backend: PHP/Laravel and Eloquent

Database: MySQL

Browser: Chrome

ISSUE

Using Javascript, I am sending data, in JSON format, using a simple text-based input form. When testing, I use "Me & You" as a test string. However, in the browser's Network tab, I notice that the JSON data takes the form of

book: {
    title: "Me & You"
...
}

PHP/Laravel saves this string as it is in the database (Me & You). Since I am also retrieving titles, even my frontend text field displays Me & You as well.

REQUIRED BEHAVIOUR

It should save the string anyway it is (Me & You) but before retrieving the entries, it should escape the special character so I receive Me & You.

Any other suggestions would be appreciated as well. I just need to escape the ampersand character.

WHAT I HAVE ALREADY TRIED

I have tried the following to solve the issue, but to no avail:

  1. Before saving the Model using Laravel's save function, I use htmlspecialchars_decode() to decode the string, but it still gives me Me & You both in the database and in the frontend.
    $title= htmlspecialchars_decode($title);
  1. I tried html_entity_decode, but still no luck.
    $title= html_entity_decode($title);
  1. I am also retrieving the titles, so I figured instead of decoding the string, I would let it save the string as it is in the table. But when I am retrieving the titles, I would decode them and then return them back to the fronend via a response.
    foreach ($user->books as &$book) {
       $book['title'] = urldecode(($book['title']));
    }

But I still receive Me & You. Note that here I am using references, because at first I thought that the foreach loop was creating a new temporary variable and not changing the original values.

  1. In javascript, I tried to use encodeURIComponent()
 book.title = encodeURIComponent(book.title);

which gives me Me%20%26%20You.

In PHP, I then try to use urldecode(), htmlspecialchars_decode() etc. but I STILL get Me & You.

Any help would be appreciated.

Thank you.

iam-9
  • 11
  • 3
  • 1
    Sounds like it is double encoded `var_dump($title)` gives what? Ideally you'd save unescaped and only escape when outputting to DOM. – user3783243 Oct 06 '20 at 13:03
  • The main question is how the ampersand gets converted into an HTML entity in the first place; this doesn't happen for me here: https://jsfiddle.net/mqjn43fe/ –  Oct 06 '20 at 13:12
  • @user3783243 I'm sorry, but I do not know how to use `var_dump` in laravel, since I am doing decoding in api controller function. But if you are curious as to what the output of the `$title` is, then it still `Me & You` in the console. – iam-9 Oct 06 '20 at 13:12
  • @ChrisG Indeed that is correct. Perhaps I should have been more clearer in my question. In the frontend, I am using Angular6/Typescript, and I get `Me & You` when I view the Network tab. I tried using encodeURIcomponents, and I get `Me%20%26%20You`, but I still can not decode it in the backend – iam-9 Oct 06 '20 at 13:15
  • Forget encodeURIComponent; as you can see it doesn't help here at all. Use `htmlspecialchars_decode()`: https://ideone.com/tOfQru (since you say you've already tried this, please show the actual code you're using) –  Oct 06 '20 at 13:21
  • @ChrisG From point #3, I am using the actual code, but instead of ```urldecode```, I used ```$book['title'] = htmlspecialchars_decode(($book['title']));``` Though I am not sure what other parts of the code you would like to see. – iam-9 Oct 06 '20 at 13:37
  • So you're using ajax to load JSON from the server? Then insert it into an angular template? Have you tried `
    `? This should handle HTML entities.
    –  Oct 06 '20 at 13:41
  • @ChrisG No, not AJAX. I am using Angular 6 data binding and displaying it in the HTML using ```{{ book.title }}``` – iam-9 Oct 06 '20 at 13:44
  • So how do you load the mysql data into your Angular app? –  Oct 06 '20 at 13:46
  • @ChrisG Your suggestion to use ```
    ``` solved half of problem, and I cannot thank you enough. I now have special characters escaped. So thank you very much! As for the loading of data, I use observables, similar to https://stackoverflow.com/questions/36395252/how-to-get-data-from-observable-in-angular2 However, I still can not understand why PHP/Laravel is not escaping special characters
    – iam-9 Oct 06 '20 at 13:51
  • @ChrisG My main issue is the that I want special characters escaped in PHP/Laravel – iam-9 Oct 06 '20 at 13:54
  • Ok, so the other half would be storing `Me & You` in the database instead of the `&` version? JSON/Laravel doesn't care about the difference, they both use the string as-is. Something is converting it to HTML entities, presumable before the request is sent. You still haven't posted any relevant code, so I can't help you with this. –  Oct 06 '20 at 13:55
  • 1
    `&amp` is an HTML entity. Not a database entity, or any other thing. Don't store values in the database like that. End of story! – miken32 Oct 06 '20 at 15:57
  • @miken32 I agree with you completely. But when I try to save the string in the database, I try to escape the character, using the methods described in my question. But it still saves `&` as `&`. I even went the other way: allowing to save the string in the database however the string is, and, when retrieving, escape the character before sending it back to the frontend. But it still shows `&` – iam-9 Oct 08 '20 at 08:54
  • There is not mention of encoding in the question, only decoding. Escaping and encoding shouldn't be needed for storage. Use parameterized queries and prepared statements. If the data is susceptible to XSS it will on output to the dom so encode on the output as escaped data (e.g. `&` instead of `&`). – user3783243 Oct 08 '20 at 22:16

0 Answers0