mdittmer / web-apis

Playground for better understanding Web APIs
Apache License 2.0
18 stars 10 forks source link

Data from UC 11.7.8.958 and later is different when re-collecting #52

Open foolip opened 6 years ago

foolip commented 6 years ago

In API surface in Chrome, UC and QQ for Android there's something strange going on with CustomEvent, and when collecting the data again from UC 11.7.8.958 on the same phone (although reinstalled, not upgraded in a sequence, and Google Play Services having been upgraded) thing look different.

This appears in the output and doesn't show up if collected anew: function (e,t){if(!e)throw Error('TypeError: Failed to construct \"CustomEvent\": An event name must be provided.');var n;if(t=t||{bubbles:!1,cancelable:!1,detail:null},\"createEvent\"in document)try{n=document.createEvent(\"CustomEvent\"),n.initCustomEvent(e,t.bubbles,t.cancelable,t.detail)}catch(l){n=document.createEvent(\"Event\"),n.initEvent(e,t.bubbles,t.cancelable),n.detail=t.detail}else n=new Event(e,t),n.detail=t&&t.detail||null;return n}

Or pretty-printed:

function(e, t) {
  if (!e) throw Error('TypeError: Failed to construct "CustomEvent": An event name must be provided.');
  var n;
  if (t = t || {
      bubbles: !1,
      cancelable: !1,
      detail: null
    }, "createEvent" in document) try {
    n = document.createEvent("CustomEvent"), n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail)
  } catch (l) {
    n = document.createEvent("Event"), n.initEvent(e, t.bubbles, t.cancelable), n.detail = t.detail
  } else n = new Event(e, t), n.detail = t && t.detail || null;
  return n
}

Possibly there's some script that's being injected, but not always. AFAICT, this hasn't been part of the Chromium source tree.

foolip commented 6 years ago

There was also a global K that went away when recollecting data. Weird.

foolip commented 6 years ago

URLSearchParams has a problem similar to the CustomEvent problem, but a problem that doesn't go away when collecting the data again, at least not this time.

Where it says "function URL() { [native code] }" or URL, it says "function (e){if(e&&\"object\"==typeof e&&t(e)){var a=new r;return n(e).forEach(function(e){if(!t(e))throw TypeError();var r=n(e);if(2!==r.length)throw TypeError();a.append(r[0],r[1])}),a}return e&&\"object\"==typeof e?(a=new r,Object.keys(e).forEach(function(t){a.set(t,e[t])}),a):new r(e)}" for URLSearchParam. Pretty-printed:

function(e) {
  if (e && "object" == typeof e && t(e)) {
    var a = new r;
    return n(e).forEach(function(e) {
      if (!t(e)) throw TypeError();
      var r = n(e);
      if (2 !== r.length) throw TypeError();
      a.append(r[0], r[1])
    }), a
  }
  return e && "object" == typeof e ? (a = new r, Object.keys(e).forEach(function(t) {
    a.set(t, e[t])
  }), a) : new r(e)
}

So it looks there are parts of UC implemented in JS, probably in a way that doesn't get the prototypes quite right. Searching for "if(" one can spot more things like this, for example execCommand seems to be replaced. And something around Array.prototype.contains and Array.prototype.includes.

Given that the results don't seem to be the same reliably, it's hard to know what to make of this, except that it is web-observable and could possibly affect web developers.

foolip commented 6 years ago

Funny, trying to isolate where the differences from 11.8.2.962 came from by running the collection yet again with the data saver enabled and disabled, suddenly I have UC version 11.8.3.963. It appears that UC upgrades itself without the help of any app store. 11.8.3.963 is newer than can currently be downloaded from uc.cn :)

foolip commented 6 years ago

OK, so collecting a few more times, it looks like the API surface changes in subtle ways each time and I can't really spot what the stable thing is supposed to be. Must be some injected scripts, and this is an issue we'll have to raise with UC. Until the there will just be some noise in the data.