12 ms·
iOS 12 Safari Array reverse bug
- maxwellito 8y agoIronically, I got an ad banner for Apple at the top of this page. Saying "Engineer in Europe. Innovate at Apple." However, this bug sounds pretty serious! :-S
- kuon 8y agoThis sounds like a very bad bug, I wonder how bad it is "in the wild".
- dan-robertson 8y agoI suspect bad. Literal data is common. Reversing is (reasonably) common. The spec required that whenever one constructs data with a literal the resulting object will have a different identity, and that (regular) arrays with different identities do not alias.
- deleted 8y ago[deleted]
- ArmandGrillet 8y agoI can also see the bug on macOS with Safari 12.0. I find it quite worrying that devs already wrote a lib to fix the issue but didn't fill a bug report to Apple and shared it on SO. Anyway, a trendy HN post might be enough to get the attention of some Apple devs and I've pinged a dev just in case: https://twitter.com/ArmandGrillet/status/1042339847384518656 https://twitter.com/ArmandGrillet/status/1042339847384518656
- matkinz 8y ago>I find it quite worrying that devs already wrote a lib to fix the issue but didn't fill a bug report to Apple Why should anybody work for a megacorp for free?
- jsmeaton 8y agoThis is a strange response. Reporting a bug is likely easier than creating and maintaining a package. It’s also the better solution for users, rather than getting website operators to install yet another lib and then remember to remove it once a fix does land.
- lolc 8y agoIf you need the shim anyway to fix it for your users it doesn't particularly matter to you at what point Apple fixes this. The fix will take months to percolate in the best case anyway. It seems you also need an Applie-ID to even report a defect. So to me the unwillingness to help Apple with this is not a strange response. Especially considering Apple made Safari closed-source.
- jsmeaton 8y agoI find the response weird because the commenter had an unwillingness to do free work for a company yet publishes a package that fixes their mistake.
- lolc 8y agoWriting a bug report is work. Writing the shim is work. The bug report doesn't fix the problem right away. The shim fixes the problem right away. Reporting the bug will cause a fix for everybody eventually. Adding the shim will fix it for me. If we want to be nice to Apple - and get rid of the shim eventually - sure, we write a bug report. But if we can fix it before reporting, that gets priority.
- saagarjha 8y agoYou have a separate comment that decries the use of a polyfill. So what is the solution you’re looking for?
- deleted 8y ago[deleted]
- saagarjha 8y agoWorks on iOS 12.1’s Safari as well, but that’s to be expected assuming that Apple shipped that without knowledge of this bug.
- Cthulhu_ 8y agoI think there's a lot of people on SO that try and snipe topics like this to boost their own CV.
- abelyao 8y agoI am the publisher of SO, that polyfill answer maybe want to get more star on github. I don't know what's means of the ployfill to this big bug.
- BonesJustice 8y agoDoes Apple have a halfway decent public issue tracker? I don’t recall ever seeing one, but I’ve never gone out of my way to look for one either.
- jaegerpicker 8y agoYep it's called radar, it's here: https://developer.apple.com/bug-reporting/ https://developer.apple.com/bug-reporting/
- exikyut 8y agoradar isn't public. You need an Apple ID linked to a developer account to view reports.
- natch 8y ago...which is free and takes about ten seconds to sign up for. You can only view your own reports, but on the other hand they do fix bugs.
- jaegerpicker 8y agoIt is public, it's free to use and sign up for. The account costs zero dollars to sign up for, so I don't get the complaint.
- lolc 8y agoIf I must fix it for my users right now I must use a shim. Letting Apple know about this will probably allow me to remove the shim after months have passed. I can see why the priorities are on the shim here. I also just checked and you need an Apple-ID to report a defect in Safari. Which I for one don't have.
- mnem 8y agoI can’t think of any bug system that doesn’t require you to log in to report a bug.
- lolc 8y agoYou're right, requiring sign-up is common for these. The only bug tracker I use that doesn't have this barrier is the Debian one.
- avar 8y agoAlso the case with any RT-based tracker (Perl core, CPAN), Jira (depending on its configuration, you can create issues via E-Mail), GitLab can also be configured to allow bug creation via an E-Mail address.
- natch 8y agoOn your last point, it takes a few seconds to create an Apple ID and sign up for a free developer account. Both parts together can be done in less than a minute.
- Klathmon 8y agoAnd then you have to report the bug yourself as you can't view other people's bug reports, and if they close it as a dupe then you need to ask special permission to view the other bug, and if they grant you access then you can follow it for status updates. And that's if you can even find the right place to report this kind of thing. Some in this thread are pointing to the webkit bugtracker which I've never used, but I have used and had issues closed as dupes in the apple bugtracker with no real info other than it's a dupe of another link I can't view... It's not impossible, but it's a lot more time than I could see having to spend on something like this right now. And I don't think it's fair to criticize someone for not wanting to put that work in, especially if they found a workaround and already posted it somewhere publicly viewable. I'd much rather get a well written bug report from someone that has the time and cares rather than 10 half-assed reports from people who just want to make one so they don't get yelled at or to view the status of another bug.
- untog 8y agoLast I checked Apple's bug reporting system wasn't public. I really wish they'd change that.
- natch 8y agoYou and many black hat hackers who would love to read through a trove of exploit reports and potentially personal data submitted in uploaded system diagnostics logs.
- xnyan 8y agoSecurity through obscurity is is not useless, but its not much protection either. There are virtually countless open source projects with public bug tracking, many of which are highly public critical internet facing applications used by millions.
- donarb 8y agoIt's not necessarily security through obscurity. It's more of a privacy thing and prevents companies from mining bug reports for information about what types of software competitors are working on. Bug reports also contain code and projects that help Apple find the cause of a bug.
- TheDong 8y agoThe simple solution is a two-tiered system. The submitter can check "This report is security sensitive or has confidential information that should not be shared further than necessary to fix the bug." Most projects have this in the form of a default-public bug tracker, and private emails to the developer or security@ mailing list. It's not difficult to have both private and public bugs where the submitter chooses which is appropriate.
- natch 8y agoI love it when people think they know better than Apple, and propose simplistic non-solutions as solutions, as if some amazing people at Apple had not already spent countless hours thinking this through at a deep level. The submitter doesn't always know when they are submitting sensitive or confidential information. And that's not going to be fixed any time soon or with any simple solution. There are system diagnostics reports that can be many megabytes and contain potentially confidential information, and it would be entirely unreasonable to expect a user, even a developer user, to know how to trawl through all of these reports with a level of expertise to discern every possible case of leakage. And that's just the personal / private information... which, by the way, Apple from what I've seen seems to strive to keep OUT of the diagnostic reports, but that doesn't mean they are perfect at this. And that doesn't even begin to address the information that might be, totally unknown to the submitter, exploitable in other ways. As far as what other projects have, macOS is a highly complex operating system along with a tightly integrated ecosystem of apps and services, which is designed to, and relied on to, "just work"... while most other systems are either much smaller, or are not maintaining a level of smooth operation and security that can match the "it just works" level of reliability standard that macOS aims for. So maybe the bug reporting systems of all those other projects are appropriate for those other projects, but that doesn't make those systems and their practices appropriate for macOS.
- tomxor 8y ago> I find it quite worrying that devs already wrote a lib to fix the issue but didn't fill a bug report to Apple and shared it on SO. It is worrying... but as someone who has filed my fair share of bug reports to all the major browser projects it's also understandable. Filling good bug reports takes effort, especially for the more obscure ones to produce small and reliable test cases. In my experience only the largest projects have the man power to acknowledge let alone address all bug reports. I abandoned reporting bugs to IE, Edge and Safari long ago because this effort often goes to waste. I get it though, browsers are one of the largest most complex incoherent pieces of software everyone uses today, but that's also why I think only fully open source (well engaged) projects work well in this area. As an aside: This is the same reason I think the browser needs to get simple again (without loosing capability) - RE James Mickens thoughts on this. Then browser diversity and man power becomes a moot point.
- hnruss 8y agoI’ve reported a few browser bugs myself, none have been fixed (even years later). I’ll still do it, though, because it may help someone else out someday.
- mh8h 8y agoIsn't it this one? https://bugs.webkit.org/show_bug.cgi?id=188794 https://bugs.webkit.org/show_bug.cgi?id=188794
- scarface74 8y agoAccording to the linked SO post, it has already been corrected in a technology preview.
- nabakin 8y agoLooks like its been fixed in the new Safari Preview https://i.imgur.com/A6lm25a.png https://i.imgur.com/A6lm25a.png
- tolmasky 8y agoIn theory you absolutely need both, and the library fixes the most pressing issue: that your site might be broken today, and more importantly will remain broken forever, unless the user chooses to upgrade, since Safari does not do automatic over-the-air updates (ala Chrome on desktop) but instead bundles it’s updates with OS versions on mobile, and updates that may or may not be set to automatic on macOS. As such, you should in theory now always have a bug-detect in your code (simple to write, make two identical 2-item arrays, reverse one, check for a difference), and apply the fix if needed.
- saudioger 8y agoYou could also just yell into a pillow. Half the time it's just as effective as reporting a bug to Apple without knowing someone there. You can spend a lot of time writing a good bug report for Apple; it's annoying that they don't bother to respond at all a lot of the time.
- chrischen 8y agoApparently it’s already fixed in Safari dev preview.
- saurik 8y agoAs noted by someone else (but only as a new top-level comment), this but was already filed and already fixed on WebKit a week ago and is rdar://problem/43637041.
- JangoSteve 8y agoI don't understand what the worrying part is. The original poster of the SO question was asking a question. They didn't know if it was a bug or them misunderstanding the intended functionality. The subject literally ends with, "is bug or feature?" The people who answered it explain that it's a bug, thereby answering the question, and expand as to why they think it's a bug. One person figured out a patch. The bug was already filed and fixed nearly a month ago but doesn't seem to have been released yet to the current versions of Safari. If there's already a bug filed and marked fixed but you can see that it isn't fixed yet for the people using Safari, and it matters to you, why would sharing it be worrisome? You could argue that the person who answered with a patch didn't know the bug was already filed with Apple, and so they should have sought out how to file it before sharing it. But I think it ignores how intimidating it can be for someone to file an official bug report with a hugely popular piece of software maintained by one of the largest companies in the world. It's even more intimidating if you've done it before and the report you filed ended up being wrong (many maintainers are not very considerate when responding to mistaken bug reports, which can wreak havoc on a developer's self esteem). Meanwhile you have platforms like StackOverflow and Hacker News which vastly lower the bar in terms of needing to be right, since they operate more as conversation facilitators than official registers of legitimate bugs. It's much easier to share what you think you've found with a group of your peers, than it is to go on record telling a group of experts that they've made a mistake in the thing that they're experts on. I don't know if the outcome is worrisome or not, but it definitely seems expected to me... even inevitable. It's the same reason you talk with your friends about how annoyed you are with potholes not being filled before you take your concerns to a town hall meeting. It's a way to refine your thoughts in a low-stakes settings with peers before formalizing an issue to run up the ladder.
- matkinz 8y ago>I wrote a lib to fix the bug. https://www.npmjs.com/package/array-reverse-polyfill https://www.npmjs.com/package/array-reverse-polyfill everyday we stray further from god
- realPubkey 8y agoAlso if now everyone starts to polyfill this garbage, then apple will not patch it before the next release of iOS.
- vanderZwan 8y agoWhat is extra frustrating is that this is an answer StackOverflow. The whole point is to give clear, educational explanations. Well, the solution is only 21 lines, so why not explain the code snippet instead? (function() { function buggy() { function detect() { var a = [0, 1]; a.reverse(); return a[0] === 0; } return detect() || detect(); } if(!buggy()) return; Array.prototype._reverse = Array.prototype.reverse; Array.prototype.reverse = function reverse() { if (Array.isArray(this)) this.length = this.length; return Array.prototype._reverse.call(this); } var nonenum = {enumerable: false}; Object.defineProperties(Array.prototype, { _reverse: nonenum, reverse: nonenum, }); })(); Look at how elaborate the repo is by comparison: https://github.com/fanmingfei/array-reverse-ios12 https://github.com/fanmingfei/array-reverse-ios12
- masto 8y agoIt has a nice logo though I can't find a link to the merch store or author's Patreon.
- raverbashing 8y ago> answer StackOverflow ... the solution is only 21 lines, so why not explain the code snippet instead? You answered your own question. Especially in the JS world
- KyleDavidE 8y ago? The snippet you showed is literally the exact code of the module: https://github.com/fanmingfei/array-reverse-ios12/blob/master/index.js https://github.com/fanmingfei/array-reverse-ios12/blob/maste... The rest is just tests / npm config / license
- dan-robertson 8y agoThis bug is very much like the most common mistake I see on Common Lisp stack overflow where one tries to mutate constant (quoted) data. However JavaScript has no similar notion of constant data but implementations try to infer it as an optimisation. In this case that inference was wrong. I think the memory structure looks something like: arr -> box1 -> 1,2,3,4 Reversing: arr -> box1 -> 4,3,2,1 But the data occupying the same region of memory before and after the sort. So then when the page is refreshed the JavaScript doesn’t change and the literal data must be included in the “parsed/compiled” form that is reused and so it is initialised as arr -> box2 -> 4,3,2,1 The correct behaviour should be as follows: 1. arr -> box1 -> loc1: 1,2,3,4 2. Reverse 3. arr -> box1 -> loc2: 4,3,2,1 4. Refresh 5. arr -> box2 -> loc1: 1,2,3,4 The “box” corresponds to the JavaScript object for the array (so mutating the array data can change the box, the data it points at, but not just the reference “arr” as the object might be pointed to from elsewhere). And this box has another pointer to the data for the array (and presumably some bit flag to say whether that is copy-on-write or not). This allows for more efficient array functions when the data doesn’t actually change
- 0x0 8y agoThe weirdest thing about this is the fact that the bug occurs after a page reload. Does safari cache jit code and the javascript heap/objects between pageloads?
- saagarjha 8y agoIt might just not clear the JIT cache if you reload the page.
- gsnedders 8y agoIt has a bfcache which attempts to restore page state when going backwards/forwards. My guess would be there's something wrong with the cache behaviour, leading it to restore the old heap and re-execute the JS.
- olliej 8y agoWhen JavaScript is parsed by jsc, it’s compiled to a cachable bytecode, this includes gc allocated constants for constant expressions - numbers, strings, and the underlying storage for some complex types like arrays and regexps. The cachable code is kept in a big function source->bytecode hash table. The cacheable bytecode is then “linked” to a bytecode that is optimized for execution speed. That bytecode has things like create_array, etc that can take the immutable backing store object we generated earlier. This means that if you have multiple functions with identical source code you only have to do the expensive parse+compile step once, and you end up with multiple independent functions using the same constant/immutable backing stores. This saves memory and helps performance. Unfortunately it adds complexity - now the mutable is objects have “immutable” backing stores, so you have to implement copy-on-write semantics in order to not share state between different instances of the linked code. In this case it appears that a required CoW check was missing :(
- 0x0 8y agoBug does not trigger on "Safari Technology Preview Release 65 (Safari 12.1, WebKit 13607.1.5.2)" on macOS 10.13.6. Fixed already, or not yet introduced?
- fuzzy2 8y agoI wonder if `splice`, `shift`, `unshift` and other methods that modify arrays in-place are also affected.
- vishalsharma 8y agoNow they will release iOS 13 for this :) P.S. https://www.youtube.com/watch?v=uG8bNDw6Ftc https://www.youtube.com/watch?v=uG8bNDw6Ftc
- toxik 8y agoIsn't this part of the faster loading that some Web browsers do? Essentially the idea is that the browser muddies the idea of a closed page in favour of being able to restore it faster.
- smaili 8y agoIt appears this was already reported and fixed in WebKit - https://bugs.webkit.org/show_bug.cgi?id=188794 https://bugs.webkit.org/show_bug.cgi?id=188794 but not specifically for the Safari browser.
- stuartd 8y agoArray.prototype.reverse modifies JSImmutableButterfly You have to wonder how an immutable butterfly can be modified?!
- kodablah 8y agoAn inadvertent yet apt Bradbury reference
- taspeotis 8y agoI would be most grateful if someone could please explain to me what "butterfly" is meant to be ... a metaphor of some sort I assume.
- detaro 8y agoInternal data structure of JavaScriptCore representing objects, presumably called a butterfly because it starts in the middle and spreads in both directions in memory. One side is properties of the object, the other members of its array aspect. See e.g. http://phrack.org/papers/attacking_javascript_engines.html http://phrack.org/papers/attacking_javascript_engines.html section 1.2
- panic 8y agoThis presentation has some nice illustrations: http://www.filpizlo.com/slides/pizlo-dls2017-vmil2017-jscvm-slides.pdf http://www.filpizlo.com/slides/pizlo-dls2017-vmil2017-jscvm-... (under “JSC Object Model”).
- olliej 8y agoAlmost all “immutable” types are mutatable by the runtime itself, irrespective of language or environment. A couple of examples of why “immutable” types are actually mutable: * string interning - a string may technically be immutable, but identical strings can be coalesced by the runtime. * immutable objects are not generally immortal: the runtime will eventually want to free the data, which means it must be mutable by the runtime. Basically at the runtime level if you forget to check all the correct flags you can easily do the wrong thing. If you look at the bugzilla report you can see the comment from the apple engineer about needing to fix this particular foot gun.
- peterkelly 8y agoAnd now we'll have array-reverse-polyfill showing up as a 6th-level npm dependency on our projects for years to come.
- chearon 8y agoI'm not seeing Safari 12 in the App Store (macOS 10.13.6). I wonder if they pulled the update because of this? I have Safari 11 still but my colleague got Safari 12 through the App Store.
- olliej 8y agoSafari updates on Mac come down as part of system updates, so until the Mojave timeframe updates appear
- randomsofr 8y agoI got the update for Safari yesterday, and i'm still running High Sierra
- olliej 8y agoSafari and webkit updates are pushed out to at least one, maybe two? (not sure exactly how many) major releases.
- pjc50 8y agoFinally we've discovered why people are asked in interviews to reverse an array.
- symlinkk 8y agoDoes Apple not believe in unit tests or something? This and the password login bug from a few months ago make me pretty concerned.
- olliej 8y agoWebkit has hundreds of thousands of tests running on every check in (check build.webkit.org iirc). Checking arbitrary complex interactions isn’t trivial so more complex classes of bugs can only get testing when they’re discovered.
- sitepodmatt 8y agoFixed. Scheduled. Coming to iOS 15 in 2022...
- cryptonector 8y agoShould we hold off on updating then?
- dkmar 8y agoWoah. I think I ran into this last night after updating to Safari 12 on macOS. I was typing my message into messenger.com (facebook messenger), and all of my typing was reversed. I even took a photo of it
- Razengan 8y agoAre you sure it wasn't accidental Right-to-Left input?
- kbumsik 8y agoI think Apple has to consider separating Safari (and other bundled apps) from the iOS release so that users can update a quick fix through the App Store without waiting for a new iOS update. There was a serious WebAssembly regression in iOS 11.2 that makes wasm effectively useless [1]. Devs had to disable wasm and wait for months until iOS 11.3 is released. Apple never releases a iOS hot fix just for a single Safari bug. Then why Apple don't let users to update Safari separately? [1]: https://bugs.webkit.org/show_bug.cgi?id=181781 https://bugs.webkit.org/show_bug.cgi?id=181781
- favorited 8y agoBecause this isn't "a single Safari bug." It's a bug in JavaScriptCore, which is a public system framework. Safari uses it, but so does any other app which links against it. Fixing this bug requires shipping new versions of system frameworks, which is pretty much the definition of an OS update. Or, they could bundle a separate version of the WebKit frameworks just for Safari (like the Safari Technical Preview does) – but then loading a website in your app would use a different stack of frameworks than loading that site in Safari, and no one wants that either.
- kbumsik 8y agoThat makes sense. I didn't know the Apple's system framework structure. Thanks for the explanation.