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

fix(ngSanitize): prevent decodeEntities from prepending original text… #5193

Closed
wants to merge 1 commit into from

Conversation

caitp
Copy link
Contributor

@caitp caitp commented Nov 28, 2013

Clearing the match before the conditional branch seems to (inexplicably)
break Safari 7 on OSX 10.9, except when stepping through line by line.

Moving the assignment to after the conditional branch corrects this
behaviour.

Closes #5192

@mary-poppins
Copy link

Thanks for the PR!

  • Contributor signed CLA now or in the past
    • If you just signed, leave a comment here with your real name
  • PR's commit messages follow the commit message format

If you need to make changes to your pull request, you can update the commit with git commit --amend.
Then, update the pull request with git push -f.

Thanks again for your help!

@caitp
Copy link
Contributor Author

caitp commented Nov 28, 2013

Oh this is fun, Safari 7 fails all kinds of tests apparently with origin/master (https://gist.github.com/caitp/7699674) --- But passes everything with this change. Weirdness.

(the one travis failure Firefox 25.0.0 (Windows 8): Executed 0 of 0 DISCONNECTED (11.352 secs / 0 secs) doesn't explain much, I'm fairly sure this patch didn't break it)

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't really explain why moving this assignment has that strong of an effect --- the VM is doing some weird things. But it does fix the problem

@urish
Copy link

urish commented Nov 29, 2013

Thanks Caitlin !

… to output

Clearing the match before the conditional branch seems to (inexplicably)
break Safari 7 on OSX 10.9, except when stepping through line by line.

Moving the assignment to after the conditional branch corrects this
behaviour.
@alexjc
Copy link

alexjc commented Nov 29, 2013

For reference, this was also an issue on Ubuntu 13.04 and 13.10, so if you can't add OSX to the CI servers this platform would have caught it.

(EDIT: Actually, it was only a problem with QtWebKit on Ubuntu -- so an older WebKit -- harder to test. Sorry for the false hopes!)

@petebacondarwin
Copy link
Member

I wonder if the result of executing the regex is not strictly an array. So assigning to it changes things in unexpected ways

@caitp
Copy link
Contributor Author

caitp commented Nov 29, 2013

I'm not totally sure, during debugging it looks totally normal --- it seems like an optimization error or something, where the conditional block and join decide to happen before the assignment happens or something. But I'm really just guessing at what it's doing, there might be a bug open on the webkit issue tracker regarding it already, or if not, maybe there should be.

@caitp
Copy link
Contributor Author

caitp commented Dec 2, 2013

I filed a bug on webkit on friday regarding this, because I'm fairly sure this is not the expected behaviour. So just marking this here for future reference: https://bugs.webkit.org/show_bug.cgi?id=125023

@urish
Copy link

urish commented Dec 2, 2013

Good work Caitlin, it's interesting to follow up and see what is the cause for this strange behavior...

@ghost ghost assigned petebacondarwin Dec 2, 2013
@petebacondarwin
Copy link
Member

How about we make the first group in spaceRe non-capturing? Sorry I was thinking we were resetting parts[1] not parts[0].

@petebacondarwin
Copy link
Member

There is definitely something wrong with Safari 7 regex. Have a look at debuggex.com - start typing into the box and after a while it starts adding spaces to the end of your text. If you try to delete the spaces then it deletes the letters instead.

@petebacondarwin
Copy link
Member

Here is a minimal reproduction. http://plnkr.co/edit/CvKkFkvga8Pdz7cik3vf?p=preview
If you uncomment the console.log then it works correctly.

@petebacondarwin
Copy link
Member

Looks like Safari has started using the YARR regex engine, which JITs the regular expressions. It may be this that is problematic...

@petebacondarwin
Copy link
Member

OK, so I think I know what the issue is. The regex is being lazy executed. It is not running until the first read access of one of the properties on the parts object. So writing to parts[0] has no effect since it is overwritten by the regex being executed when we first access parts[2], etc.

@petebacondarwin
Copy link
Member

Maybe this changeset: https://trac.webkit.org/changeset/112454 ?

@petebacondarwin
Copy link
Member

@caitp - thanks once again for all your work on this - it saved us a load of time. I made a slightly different fix as you can see by my commit: 81b8185. I decided that making any mods to the match object was dubious and of no real benefit here anyway.

jamesdaily pushed a commit to jamesdaily/angular.js that referenced this pull request 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 pull request 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

regression in 1.2.3: ng-bind-html breaks in Safari 7 on OSX 10.9
5 participants