Breaking: Safari web browser has a nasty bug on iOS 12
Update (September 20): It’s a WebKit bug that has been fixed, but is yet to make way to Safari. More info here.
Update (September 19): The bug is slowly gaining attraction of developers:
@cleatsupkeep Hello, saw this important Safari bug on HN but I'm not sure if I should report it to Apple or the WebKit org and I don't have time to look further, could you please take a look? https://t.co/KfiSVgKvkP
— Armand Grillet (@ArmandGrillet) September 19, 2018
This same guy posted on Hacker News that they could reproduce the problem on Safari 12.0 running on Mac OS as well.
I can also see the bug on macOS with Safari 12.0
Original story follows:
Major updates usually bring along some problems or issues. As long as bugs are not big, things go on smoothly, and the issues are fixed in subsequent updates.
However, sometimes, a major bug makes way to the stable release. And looks like the same has happened with Apple’s newest iOS 12 update.
Aside from some not-so-big problems (that we’ve already highlighted here), it has now come to light that there’s a major bug in Apple’s Safari web browser in iOS 12.
The problem can be reproduced when you try refreshing an HTML page that runs the java script reverse() function on an array.
Ideally, a page refresh should reset the array value to its original form, but on iOS 12, this is not happening.
The array continues to contain reversed values even after a page refresh. For example, here’s a sample code:
This code basically takes an array (1,2,3,4,5) and reverses it (5,4,3,2,1) when user presses the button on the html page.
However, if you reload the html page, the array should again show the original value, which is (1,2,3,4,5).
We first tested this code on an iPhone running iOS 11.4.1, and as you can see in screenshots below, the code worked as expected.
You can see the page refresh operation showed the array values as 1,2,3,4,5. So that’s correct.
Oh, and you can see, Safari showed reversed array values even after a page refresh. So that’s clearly a problem.
We’re not sure about the exact reason behind the problem, but as someone on StackOverFlow (where the issue was first reported) explains:
It’s definitely a BUG! And it’s a very serious bug.
As my test, the bug is due to the optimization of array initializer which all values are primitive literal. For example () => [1, null, ‘x’] will return such arrays, and all return arrays link to same memory address, and some method like toString() is also memorized. Normally, any mutable operation on such array will copy to a individual memory space and link to it, this is so-called copy-on-write technique (https://en.wikipedia.org/wiki/Copy-on-write).
reverse() method will mutate the array, so it should trigger CoW, Unfortunately, it doesn’t now, which cause bug.
On the other hand, all methods which do not modify the array should not trigger CoW, and I find that even a.fill(value, 0, 0) or a.copyWithin(index, 0, 0) won’t trigger CoW because such callings don’t really mutate the array. But I notice that a.slice() WILL trigger CoW. So I guess the real reason of this bug may be someone accidentally swap the index of slice and reverse.
We’ll update the story as and when there’s more news to share on this front.
PiunikaWeb is a unique initiative that mainly focuses on investigative journalism. This means we do a lot of hard work to come up with news stories that are either ‘exclusive,’ ‘breaking,’ or ‘curated’ in nature. Perhaps that’s the reason our work has been picked by the likes of Forbes, Engadget, The Verge, Macrumors, and more. Do take a tour of our website to get a feel of our work. And if you like what we do, stay connected with us on Twitter (@PiunikaWeb) and other social media channels to receive timely updates on stories we publish.