Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

regression in 1.2.3: ng-bind-html breaks in Safari 7 on OSX 10.9 #5192

Closed
urish opened this issue Nov 28, 2013 · 12 comments
Closed

regression in 1.2.3: ng-bind-html breaks in Safari 7 on OSX 10.9 #5192

urish opened this issue Nov 28, 2013 · 12 comments

Comments

@urish
Copy link

urish commented Nov 28, 2013

For some reason, ng-bind-html renders the given text twice on Safari 7. This seems to be a regression in ngSanitize 1.2.3.

The following Plunker reproduces the issue:

http://plnkr.co/edit/4tXYKqp3p5dmiMrmIUNI?

It only reproduces on Safari 7.0 (It didn't reproduce on Safari 6.0.5/Chrome latest/Firefox latest/IE9/IE10). Also, if you change the Plunker to use ngSanitize version 1.2.2, the issue is gone and ng-bind-html functions as expected.

Here is the expected output v.s. the actual output from the above Plunker code:

Expected Output

<div ng-bind-html="name" class="ng-binding"><strong>John Due ☺</strong></div>

Actual Output with Safari 7 and ngSanitize 1.2.3

<div ng-bind-html="name" class="ng-binding"><strong>John Due &amp;#9786;John Due ☺</strong></div>
@caitp
Copy link
Contributor

caitp commented Nov 28, 2013

The issue seems to happen in decodeEntities, and it doesn't really make sense.

If you step through line by line, it actually works correctly --- but if you instead break at the end of the routine, it appears that parts[0] is never cleared (as though line 376 never happened), and so the total match + the inner text are all joined together.

I can't really explain that --- browser bug maybe? but it seems like it's probably easy to work around it

@caitp
Copy link
Contributor

caitp commented Nov 28, 2013

Well, I don't think this is a very good patch, but it does solve the issue --- if someone has an alternative solution that works too, I'm in favour of an alternative.

@urish
Copy link
Author

urish commented Nov 28, 2013

How about parts.shift() and move it to be after the if?

@caitp
Copy link
Contributor

caitp commented Nov 29, 2013

Heh, it is truly bizar.

This fails:

  parts[0] = '';
  if (parts[2]) {
    hiddenPre.innerHTML=parts[2].replace(/</g,"&lt;");
    parts[2] = hiddenPre.innerText || hiddenPre.textContent;
  }

but this passes:

  if (parts[2]) {
    hiddenPre.innerHTML=parts[2].replace(/</g,"&lt;");
    parts[2] = hiddenPre.innerText || hiddenPre.textContent;
  }
  parts[0] = '';

I guess that's probably a better solution though, so I'll try that in the plnkr just to double check


http://plnkr.co/edit/8NBJCzK8YMIRGNb8cQ2p?p=preview this version works alright

It's a real shame SauceLabs doesn't support Mavericks / Safari 7 yet :(

@urish
Copy link
Author

urish commented Nov 29, 2013

True, at least now we have a working solution for this. Thanks for taking the time to test and fix this!

@jeffwhelpley
Copy link

I ran into this today. It is one of those "this doesn't make any sense" bugs. Glad to see a fix is already in place. Thanks, @caitp.

@scottbaggett
Copy link

This issue is back in 1.2.10

@caitp
Copy link
Contributor

caitp commented Jan 23, 2014

Do you have a repro for this?

@scottbaggett
Copy link

Unfortunately I don't, I just noticed it on our dev site when I upgraded from 1.2.4 to 1.2.10.

@caitp
Copy link
Contributor

caitp commented Jan 23, 2014

If you can isolate the issue and write a small reproduction that would be a big help, do you have time for that @scottbaggett?

@scottbaggett
Copy link

Right now I don't, I'm under a super tight deadline. I've got to roll back for now. I'll try to find some time to help though.

@scottbaggett
Copy link

I just updated to v1.2.10-build.2178+sha.40dc806 and the issue is no longer appearing for me. I'm going to go ahead and assume it was something on my end but if I see it again I'll note it and try to help debug it.

jamesdaily pushed a commit to jamesdaily/angular.js that referenced this issue Jan 27, 2014
In Safari 7 (and other browsers potentially using the latest YARR JIT library)
regular expressions are not always executed immediately that they are called.
The regex is only evaluated (lazily) when you first access properties on the `matches`
result object returned from the regex call.

In the case of `decodeEntities()`, we were updating this returned object, `parts[0] = ''`,
before accessing it, `if (parts[2])', and so our change was overwritten by the result
of executing the regex.

The solution here is not to modify the match result object at all. We only need to make use
of the three match results directly in code.

Developers should be aware, in the future, when using regex, to read from the result object
before making modifications to it.

There is no additional test committed here, because when run against Safari 7, this
bug caused numerous specs to fail, which are all fixed by this commit.

Closes angular#5193
Closes angular#5192
jamesdaily pushed a commit to jamesdaily/angular.js that referenced this issue Jan 27, 2014
In Safari 7 (and other browsers potentially using the latest YARR JIT library)
regular expressions are not always executed immediately that they are called.
The regex is only evaluated (lazily) when you first access properties on the `matches`
result object returned from the regex call.

In the case of `decodeEntities()`, we were updating this returned object, `parts[0] = ''`,
before accessing it, `if (parts[2])', and so our change was overwritten by the result
of executing the regex.

The solution here is not to modify the match result object at all. We only need to make use
of the three match results directly in code.

Developers should be aware, in the future, when using regex, to read from the result object
before making modifications to it.

There is no additional test committed here, because when run against Safari 7, this
bug caused numerous specs to fail, which are all fixed by this commit.

Closes angular#5193
Closes angular#5192
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.