Breaking news : un problème agaçant du navigateur Safari survient sur iOS 12

Écrit par Gaëlle Lemoine  Oct 22, 2018

« Bonjour, j'ai remarqué cet important problème Safari sur HN mais je ne suis pas sûr si je dois en faire part à Apple ou sur WebKit org et je n'ai pas le temps de m'en occuper, pourriez-vous m'aider s'il vous plaît ? »
— Armand Grillet (@ArmandGrillet) le 19 septembre 2018

Cette personne a posté sur Hacker News que ces problèmes pourraient également se produire sur Safari 12.0 qui marche sur Mac OS.

« Ce problème avec Safari 12.0 persiste sur macOS. »

Voici l'histoire d'origine :

Les mises à jour majeures apportent souvent des problèmes ou des failles. Tant que les bogues se posent peu, tout se passera bien et les problèmes seront corrigés dans les mises à jour ultérieures.

Cependant, la stabilité d'une version l'emporte parfois sur une erreur majeure et il semble que la même chose s’est déroulée avec la dernière mise à jour Apple : iOS 12.

À part des problèmes généraux (que nous avons mis en valeur ici), il est maintenant évident qu’une erreur majeure se présentait dans le navigateur Web Safari d’Apple dans iOS 12.

Le problème peut se reproduire lorsque vous essayez d'actualiser une page HTML, ce qui lance la fonction javascript reverse() sur un tableau.

Idéalement, une actualisation de page devrait réinitialiser la valeur du tableau à sa forme d'origine, mais cela ne se produit pas sur iOS 12.

Le tableau continue à contenir des valeurs inversées même après une actualisation de la page. Par exemple, voici un exemple de code :

Ce code prend généralement un tableau (1,2,3,4,5,) et le renverse (5,4,3,2,1) lorsque les utilisateurs appuient sur le bouton de la page html.

Cependant, si vous rechargez la page html, le tableau doit montrer à nouveau la valeur originale : (1,2,3,4,5).

Nous avons d'abord testé ce code sur un iPhone qui lance iOS 11.4.1 et comme ce que présentent les captures d'écran ci-dessous, le code a fonctionné comme prévu.

Voici la preuve du téléphone qui lance iOS 11.4.1 :

Voici la sortie lorsque nous chargions la page :

Puis on a cliqué sur le bouton (Array.reverse) sur la page, qui a été suivi d'une actualisation de page.

Si vous vous rendez compte que la manipulation de l'actualisation de page a montré les valeurs du tableau (1,2,3,4,5), ça y est.

Maintenant, nous avons pris un appareil sous iOS 12 (un iPad en ce cas).

Voici le résultat lorsque nous chargions la page :

Par la suite, juste comme ce que nous avons précédemment fait, nous avons pressé sur le bouton (Array.reverse) de la page puis effectué une actualisation de page.

À propos, Safari présente les valeurs du tableau renversé même après le renouvellement de la page et c'est clairement un problème.

Donc effectivement, Safari sur iOS 12 rompt les codes Javascript qui utilise la fonction reverse().

Nous ne sommes pas sûrs de la cause exacte derrière le problème mais comme ce que quelqu'un explique sur StackOverFlow (où le problème a été reporté dans un premier temps) :

C'est définitivement un BOGUE ! Et c'est un grand bogue.

Comme mon test, le problème est dû à l'optimisation d'un initiateur du tableau dont toutes les valeurs sont des littéraux primitifs. Par exemple () => [1, null, ‘x’] renverras de tels tableaux et tous les tableaux renvoyés sont liés à une même addresse mémoire et des méthodes telles que toString() sont aussi mémorisées.

Normalement, toute opération mutable sur tel tableau sera copiée sur un espace mémoire individuel et le relie, c'est la soi-disant technique de copy-on-write (https://en.wikipedia.org/wiki/Copy-on-write).

La méthode reverse() transposera le tableau, alors il doit provoquer CoW. Malheureusement, c'est peine perdue, ce qui se fait une erreur.

D'autre part, toutes les méthodes qui ne modifient pas le tableau ne doit pas susciter CoW et j'ai remarqué que même a.fill(value, 0, 0) et a.copyWithin(index, 0, 0) ne suscitera pas CoW parce que de tels appels ne changent réellement le tableau. Mais je me suis aperçu qu'un slice() WILL suscite CoW. C'est pourquoi je suppose que la cause réelle de cette erreur vient peut-être d'une certaine personne qui se trompe de l'index de slice et celui de reverse.

Nous renouvèlerons l'histoire s'il y a plus de nouvelles à partager.