From b902ec74ad148d3c9122491c4d47299553d3cc8c Mon Sep 17 00:00:00 2001 From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Fri, 14 Feb 2020 07:46:11 +0100 Subject: [PATCH] Release 80.0.3987.95 --- CHANGELOG.md | 5 ++ build/bromite_patches_list.txt | 2 +- .../Add-option-to-use-home-page-as-NTP.patch | 2 +- .../Automated-domain-substitution.patch | 4 +- .../Enable-user-agent-freeze-by-default.patch | 23 ++++++++ ...tracking-ads-and-video-functionality.patch | 4 +- build/patches/User-Agent-anonymize.patch | 59 ------------------- 7 files changed, 34 insertions(+), 65 deletions(-) create mode 100644 build/patches/Enable-user-agent-freeze-by-default.patch delete mode 100644 build/patches/User-Agent-anonymize.patch diff --git a/CHANGELOG.md b/CHANGELOG.md index e73ac422..b27754ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 80.0.3987.95 +* enable user-agent freeze (fixes https://github.com/bromite/bromite/issues/483) +* fix issue with AMP (fixes https://github.com/bromite/bromite/issues/488) +* fix crash on home page (fixes https://github.com/bromite/bromite/issues/484) + # 80.0.3987.78 * removed ungoogled-chromium patch for non-remote developer tools resources * removed patch for 64-bit webview (it is now a default from upstream) diff --git a/build/bromite_patches_list.txt b/build/bromite_patches_list.txt index 59883c7e..1534530c 100644 --- a/build/bromite_patches_list.txt +++ b/build/bromite_patches_list.txt @@ -52,7 +52,6 @@ Add-flag-to-control-video-playback-resume-feature.patch Open-YouTube-links-in-Bromite.patch Add-exit-menu-item.patch Remove-help-menu-item.patch -User-Agent-anonymize.patch AudioBuffer-AnalyserNode-fingerprinting-mitigations-via-IDL.patch Multiple-fingerprinting-mitigations-for-canvas-text-and-client-rectangles.patch Add-flags-to-disable-device-motion-and-orientation-APIs.patch @@ -136,4 +135,5 @@ Restore-enable-horizontal-tab-switcher-flag.patch Use-a-minimum-DoH-timeout-of-400ms.patch Disable-DRM-media-origin-IDs-preprovisioning.patch Disable-smart-selection-by-default.patch +Enable-user-agent-freeze-by-default.patch Automated-domain-substitution.patch diff --git a/build/patches/Add-option-to-use-home-page-as-NTP.patch b/build/patches/Add-option-to-use-home-page-as-NTP.patch index 6236d750..6bd68252 100644 --- a/build/patches/Add-option-to-use-home-page-as-NTP.patch +++ b/build/patches/Add-option-to-use-home-page-as-NTP.patch @@ -21,7 +21,7 @@ diff --git a/chrome/android/java/res/xml/homepage_preferences.xml b/chrome/andro -+ diff --git a/build/patches/Automated-domain-substitution.patch b/build/patches/Automated-domain-substitution.patch index 9450322e..051f3215 100644 --- a/build/patches/Automated-domain-substitution.patch +++ b/build/patches/Automated-domain-substitution.patch @@ -14193,7 +14193,7 @@ diff --git a/chrome/browser/notifications/notification_permission_context.h b/ch diff --git a/chrome/browser/notifications/notification_platform_bridge_mac.mm b/chrome/browser/notifications/notification_platform_bridge_mac.mm --- a/chrome/browser/notifications/notification_platform_bridge_mac.mm +++ b/chrome/browser/notifications/notification_platform_bridge_mac.mm -@@ -479,7 +479,7 @@ bool NotificationPlatformBridgeMac::VerifyNotificationData( +@@ -489,7 +489,7 @@ bool NotificationPlatformBridgeMac::VerifyNotificationData( // Overriden from _NSUserNotificationCenterDelegatePrivate. // Emitted when a user closes a notification from the notification center. // This is an undocumented method introduced in 10.8 according to @@ -38278,7 +38278,7 @@ diff --git a/components/sync_bookmarks/PRESUBMIT.py b/components/sync_bookmarks/ diff --git a/components/sync_bookmarks/bookmark_model_merger.cc b/components/sync_bookmarks/bookmark_model_merger.cc --- a/components/sync_bookmarks/bookmark_model_merger.cc +++ b/components/sync_bookmarks/bookmark_model_merger.cc -@@ -624,7 +624,7 @@ void BookmarkModelMerger::ProcessLocalCreation( +@@ -622,7 +622,7 @@ void BookmarkModelMerger::ProcessLocalCreation( DCHECK(parent_entity); // Similar to the directory implementation here: diff --git a/build/patches/Enable-user-agent-freeze-by-default.patch b/build/patches/Enable-user-agent-freeze-by-default.patch new file mode 100644 index 00000000..176f1a9d --- /dev/null +++ b/build/patches/Enable-user-agent-freeze-by-default.patch @@ -0,0 +1,23 @@ +From: csagan5 <32685696+csagan5@users.noreply.github.com> +Date: Mon, 10 Feb 2020 23:13:13 +0100 +Subject: Enable user-agent freeze by default + +--- + third_party/blink/common/features.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc +--- a/third_party/blink/common/features.cc ++++ b/third_party/blink/common/features.cc +@@ -46,7 +46,7 @@ const base::Feature kFreezePurgeMemoryAllPagesFrozen{ + + // Freezes the user-agent as part of https://github.com/WICG/ua-client-hints. + const base::Feature kFreezeUserAgent{"FreezeUserAgent", +- base::FEATURE_DISABLED_BY_DEFAULT}; ++ base::FEATURE_ENABLED_BY_DEFAULT}; + + // When enabled, the compositing of trivial 3D transforms is disabled. + const base::Feature kDoNotCompositeTrivial3D{"DoNotCompositeTrivial3D", +-- +2.17.1 + diff --git a/build/patches/Inject-scripts-for-AMP-tracking-ads-and-video-functionality.patch b/build/patches/Inject-scripts-for-AMP-tracking-ads-and-video-functionality.patch index 4c3f1ac5..ddf2cd61 100644 --- a/build/patches/Inject-scripts-for-AMP-tracking-ads-and-video-functionality.patch +++ b/build/patches/Inject-scripts-for-AMP-tracking-ads-and-video-functionality.patch @@ -135,7 +135,7 @@ new file mode 100644 +#ifndef anti_amp_cure_h +#define anti_amp_cure_h + -+#define ANTI_AMP_CURE_JS "/* Array of bytes to base64 string decoding */\n/* */\nfunction b64ToUint6(nChr) {\n return nChr > 64 && nChr < 91 ?\n nChr - 65 :\n nChr > 96 && nChr < 123 ?\n nChr - 71 :\n nChr > 47 && nChr < 58 ?\n nChr + 4 :\n nChr === 43 ?\n 62 :\n nChr === 47 ?\n 63 :\n 0;\n}\n\n/* returns an Uint8Array with decoded bytes */\n/* from https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#Appendix.3A_Decode_a_Base64_string_to_Uint8Array_or_ArrayBuffer */\nfunction base64DecToArr(sBase64, nBlockSize) {\n var\n // URL encoding variant\n sB64Enc = sBase64.replace('-', '+').replace('_', '/'),\n nInLen = sB64Enc.length,\n nOutLen = nBlockSize ? Math.ceil((nInLen * 3 + 1 >>> 2) / nBlockSize) * nBlockSize : nInLen * 3 + 1 >>> 2,\n aBytes = new Uint8Array(nOutLen);\n\n for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {\n nMod4 = nInIdx & 3;\n nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;\n if (nMod4 === 3 || nInLen - nInIdx === 1) {\n for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {\n aBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;\n }\n nUint24 = 0;\n }\n }\n\n return aBytes;\n}\n\nfunction replaceHyperlink(a, url) {\n // create new A element - old one has event listeners attached\n var newA = document.createElement('a');\n newA.referrerPolicy = 'no-referrer';\n // property set when hyperlink has been created by this script\n newA.sane = true;\n newA.href = url;\n // copy CSS classes - news have only one\n newA.className = a.className;\n // scan child nodes for SVGs\n // news nodes will only have a text node\n a.childNodes.forEach(function(n) {\n // remove icon from image result buttons\n if (n.nodeName == 'DIV') {\n var svgs = n.querySelectorAll('div svg');\n if (svgs.length == 2)\n n.removeChild(svgs[1]);\n }\n });\n // use direct HTML as appending nodes skips some e.g. heading\n newA.innerHTML = a.innerHTML;\n // replace hyperlink\n a.parentNode.replaceChild(newA, a);\n return newA;\n}\n\nfunction getURLFromJsData(jsdata) {\n if (!jsdata) return;\n\n var res = jsdata.split(';');\n if (res.length < 3) return;\n // decode the payload\n var data = base64DecToArr(res[1]);\n // 08 = field 1, type Variant\n if (data[0] != 0x08)\n return;\n // 13 = 19 (raw) or -10 (zigzag)\n if (data[1] != 0x13) {\n console.warn('could not decode:', res[1]);\n return;\n }\n // 22 = field 4, type String\n if (data[2] != 0x22)\n return;\n // usually 2 bytes varint e.g. 88-01 = length 136\n res = proto_read_uint32(data, 3);\n // extract slice with the URL\n return new TextDecoder().decode(data.slice(res.pos, res.pos + res.value));\n}\n\nfunction recreateNewsHyperlink(a) {\n var article = a.parentNode;\n if (!article) return false;\n // grab jsdata from parent\n var url = getURLFromJsData(article.getAttribute('jsdata'));\n // use the AMP (but external) URL as fallback\n var obfuscated = false;\n if (!url) {\n url = a.href;\n obfuscated = true;\n }\n\n // ready to replace the hyperlink\n var newA = replaceHyperlink(a, url);\n if (obfuscated)\n newA.setAttribute(\"_target\", \"blank\");\n\n // replace headline hyperlink\n var h4a = article.querySelector('h4 a');\n if (h4a) {\n var newH4a = replaceHyperlink(h4a, url);\n if (obfuscated)\n newH4a.setAttribute(\"_target\", \"blank\");\n }\n\n // remove icon by finding the time sibling\n var t = article.querySelector('time');\n if (t) {\n var found = false;\n t.parentNode.childNodes.forEach(function(n) {\n if (found) return;\n if (n.innerText == \"amp\") {\n t.parentNode.removeChild(n);\n found = true;\n }\n });\n }\n\n // cleanup of the article\n article.removeAttribute('jsmodel');\n article.removeAttribute('jsaction');\n article.removeAttribute('jscontroller');\n article.removeAttribute('jsdata');\n\n return true;\n}\n\n// from protobufjs\nfunction proto_read_uint32(buf, pos) {\n var value = (buf[pos] & 127) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n value = (value | (buf[pos] & 127) << 7) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n value = (value | (buf[pos] & 127) << 14) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n value = (value | (buf[pos] & 127) << 21) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n value = (value | (buf[pos] & 15) << 28) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n\n if ((pos += 5) > buf.length)\n throw RangeError('cannot read string length');\n\n return {\n value: value,\n pos: pos\n };\n}\n\nfunction recreateResultHyperlink(a) {\n var url = a.href;\n // remove AMP class, get actual page URL\n var ampCur = a.getAttribute('data-amp-cur');\n if (ampCur) {\n url = ampCur;\n a.classList.remove('amp_r');\n } else {\n var realLink = getRealLinkFromGoogleUrl(a);\n if (realLink) {\n url = realLink;\n } else {\n // might not be an actual hyperlink, ignore it\n if (!a.href) {\n return false;\n }\n // leave original href unchanged\n }\n }\n\n // re-create with original CSS classes\n replaceHyperlink(a, url);\n\n return true;\n}\n\nfunction isResult(a) {\n if (a.getAttribute('data-amp-cur'))\n return true;\n var inlineMousedown = a.getAttribute('onmousedown');\n if (!inlineMousedown)\n return false;\n // return rwt(....); // E.g Google search results.\n // return google.rwt(...); // E.g. sponsored search results\n // return google.arwt(this); // E.g. sponsored search results (dec 2016).\n return /\\ba?rwt\\(/.test(inlineMousedown) || /\\bctpacw\\b/.test(inlineMousedown);\n}\n\n/**\n * @returns {String} the real URL if the given link is a Google redirect URL.\n */\nfunction getRealLinkFromGoogleUrl(a) {\n if ((a.hostname === location.hostname || a.hostname.indexOf('www.google.') == 0) &&\n /^\\/(local_)?url$/.test(a.pathname)) {\n // Google Maps / Dito (/local_url?q=)\n // Mobile (/url?q=)\n var url = /[?&](?:q|url)=((?:https?|ftp)[%:][^&]+)/.exec(a.search);\n if (url)\n return decodeURIComponent(url[1]);\n // Help pages, e.g. safe browsing (/url?...&q=%2Fsupport%2Fanswer...)\n url = /[?&](?:q|url)=((?:%2[Ff]|\\/)[^&]+)/.exec(a.search);\n if (url)\n return a.origin + decodeURIComponent(url[1]);\n }\n}\n\nfunction sanitizeAds() {\n // scan all divs\n var div = document.getElementById('tads');\n if (div) {\n div.style.display = 'none';\n return true;\n }\n return false;\n}\n\nfunction hookMoreSearchResults() {\n var extrares = document.getElementById('extrares');\n if (!extrares) {\n console.warn(\"could not hook more results\");\n return;\n }\n // mutation observers are great but they don't work\n extrares.addEventListener(\"DOMNodeInserted\", function(e) {\n var node = e.target;\n if (node.id && node.id.startsWith(\"arc-srp\"))\n sanitizeResultHyperlinks(node);\n });\n}\n\nfunction setMlogoClick() {\n // skip home page\n if (document.getElementById('hplogo')) return;\n\n var mlogo = document.getElementById('qslc');\n if (mlogo && mlogo.children[0]) {\n mlogo = mlogo.children[0];\n } else {\n mlogo = document.getElementById('mlogo');\n }\n if (mlogo) {\n mlogo.removeAttribute(\"href\");\n mlogo.setAttribute(\"onclick\", \"sanitizeAll()\");\n console.log(\"logo link replaced\");\n } else {\n console.warn(\"could not replace logo link\");\n }\n}\n\nfunction sanitizeResultHyperlinks(rootNode) {\n var sanitized = 0,\n total = 0;\n // exclude translation hyperlink nodes\n const exclude = rootNode.querySelectorAll('#tw-ob a');\n // selector for results (doesn't work with news anymore)\n rootNode.querySelectorAll('div[data-hveid]:not([data-hveid=\"\"]) a, div[data-ved]:not([data-ved=\"\"]) a').forEach(function(a) {\n // exclude nodes which should not be processed\n var excluded = false;\n exclude.forEach(function(e) {\n if (excluded) return;\n if (e == a) {\n excluded = true;\n }\n });\n if (excluded) return;\n\n total++;\n if (!a.sane && recreateResultHyperlink(a))\n sanitized++;\n });\n console.log(\"sanitized \", sanitized, \"/\", total, \" result hyperlinks\");\n}\n\nfunction sanitizeAllNews() {\n var sanitized = 0,\n total = 0;\n // pick all articles which have the associated data not yet wiped\n document.querySelectorAll('article[jsdata]:not([jsdata=\"\"]) a').forEach(function(a) {\n total++;\n if (!a.sane && recreateNewsHyperlink(a))\n sanitized++;\n });\n console.log(\"sanitized \", sanitized, \"/\", total, \" news hyperlinks\");\n}\n\nfunction hookMoreNews() {\n document.addEventListener(\"DOMNodeInserted\", function(e) {\n var node = e.target;\n // the real inserted node is 'C-WIZ', but we need to wait for loading to complete\n if (node.nodeName == '#text' && node.parentNode && node.parentNode.nodeName == 'TITLE')\n // title is updated when page loading completes, thus trigger hyperlinks fixing afterwards\n sanitizeAllNews();\n });\n}\n\nfunction hookMoreImageResults() {\n document.addEventListener(\"DOMNodeInserted\", function(e) {\n var node = e.target;\n // remove card and iframe, fix hyperlink\n if (node.nodeName == \"DIV\" && node.hasAttribute(\"data-query\"))\n sanitizeResultHyperlinks(node);\n else if (node.nodeName == \"IFRAME\")\n node.parentNode.removeChild(node);\n else if (node.nodeName == \"C-WIZ\")\n // replace instead of removing so that correlated image results will be displayed\n node.parentNode.replaceChild(node, document.createTextNode(\"iframe replaced\"));\n });\n}\n\nconsole.log('Bromite click-tracking and AMP removal v0.4.2');\n\nif (document.location.host.indexOf(\"news.google.\") === 0) {\n sanitizeAllNews();\n hookMoreNews();\n} else {\n // avoid running cleanup on non-result pages\n if (document.location.host.indexOf(\"accounts.google.\") == -1) {\n console.log(\"ads removed: \", sanitizeAds());\n\n if (document.location.search.match(/[?&]tbm=isch/)) {\n // find main c-wiz\n var cwizs = document.querySelectorAll('c-wiz[data-ssc=\"0\"]');\n if (cwizs.length)\n sanitizeResultHyperlinks(cwizs[0]);\n else\n console.warning('could not find main image results');\n // image search results\n hookMoreImageResults();\n } else {\n var main = document.getElementById('main');\n if (main)\n sanitizeResultHyperlinks(main);\n else\n console.warning('could not find main search results');\n // regular search results\n setMlogoClick();\n hookMoreSearchResults();\n }\n }\n}\n" ++#define ANTI_AMP_CURE_JS "/* Array of bytes to base64 string decoding */\n/* */\nfunction b64ToUint6(nChr) {\n return nChr > 64 && nChr < 91 ?\n nChr - 65 :\n nChr > 96 && nChr < 123 ?\n nChr - 71 :\n nChr > 47 && nChr < 58 ?\n nChr + 4 :\n nChr === 43 ?\n 62 :\n nChr === 47 ?\n 63 :\n 0;\n}\n\n/* returns an Uint8Array with decoded bytes */\n/* from https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#Appendix.3A_Decode_a_Base64_string_to_Uint8Array_or_ArrayBuffer */\nfunction base64DecToArr(sBase64, nBlockSize) {\n var\n // URL encoding variant\n sB64Enc = sBase64.replace('-', '+').replace('_', '/'),\n nInLen = sB64Enc.length,\n nOutLen = nBlockSize ? Math.ceil((nInLen * 3 + 1 >>> 2) / nBlockSize) * nBlockSize : nInLen * 3 + 1 >>> 2,\n aBytes = new Uint8Array(nOutLen);\n\n for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {\n nMod4 = nInIdx & 3;\n nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;\n if (nMod4 === 3 || nInLen - nInIdx === 1) {\n for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {\n aBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;\n }\n nUint24 = 0;\n }\n }\n\n return aBytes;\n}\n\nfunction replaceHyperlink(a, url) {\n // create new A element - old one has event listeners attached\n var newA = document.createElement('a');\n newA.referrerPolicy = 'no-referrer';\n // property set when hyperlink has been created by this script\n newA.sane = true;\n newA.href = url;\n // copy CSS classes - news have only one\n newA.className = a.className;\n // scan child nodes for SVGs\n // news nodes will only have a text node\n a.childNodes.forEach(function(n) {\n // remove icon from image result buttons\n if (n.nodeName == 'DIV') {\n var svgs = n.querySelectorAll('div svg');\n if (svgs.length == 2)\n n.removeChild(svgs[1]);\n }\n });\n // use direct HTML as appending nodes skips some e.g. heading\n newA.innerHTML = a.innerHTML;\n // replace hyperlink\n a.parentNode.replaceChild(newA, a);\n return newA;\n}\n\nfunction getURLFromJsData(jsdata) {\n if (!jsdata) return;\n\n var res = jsdata.split(';');\n if (res.length < 3) return;\n // decode the payload\n var data = base64DecToArr(res[1]);\n // 08 = field 1, type Variant\n if (data[0] != 0x08)\n return;\n // 13 = 19 (raw) or -10 (zigzag)\n if (data[1] != 0x13) {\n console.warn('could not decode:', res[1]);\n return;\n }\n // 22 = field 4, type String\n if (data[2] != 0x22)\n return;\n // usually 2 bytes varint e.g. 88-01 = length 136\n res = proto_read_uint32(data, 3);\n // extract slice with the URL\n return new TextDecoder().decode(data.slice(res.pos, res.pos + res.value));\n}\n\nfunction recreateNewsHyperlink(a) {\n var article = a.parentNode;\n if (!article) return false;\n // grab jsdata from parent\n var url = getURLFromJsData(article.getAttribute('jsdata'));\n // use the AMP (but external) URL as fallback\n var obfuscated = false;\n if (!url) {\n url = a.href;\n obfuscated = true;\n }\n\n // ready to replace the hyperlink\n var newA = replaceHyperlink(a, url);\n if (obfuscated)\n newA.setAttribute(\"_target\", \"blank\");\n\n // replace headline hyperlink\n var h4a = article.querySelector('h4 a');\n if (h4a) {\n var newH4a = replaceHyperlink(h4a, url);\n if (obfuscated)\n newH4a.setAttribute(\"_target\", \"blank\");\n }\n\n // remove icon by finding the time sibling\n var t = article.querySelector('time');\n if (t) {\n var found = false;\n t.parentNode.childNodes.forEach(function(n) {\n if (found) return;\n if (n.innerText == \"amp\") {\n t.parentNode.removeChild(n);\n found = true;\n }\n });\n }\n\n // cleanup of the article\n article.removeAttribute('jsmodel');\n article.removeAttribute('jsaction');\n article.removeAttribute('jscontroller');\n article.removeAttribute('jsdata');\n\n return true;\n}\n\n// from protobufjs\nfunction proto_read_uint32(buf, pos) {\n var value = (buf[pos] & 127) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n value = (value | (buf[pos] & 127) << 7) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n value = (value | (buf[pos] & 127) << 14) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n value = (value | (buf[pos] & 127) << 21) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n value = (value | (buf[pos] & 15) << 28) >>> 0;\n if (buf[pos++] < 128) return {\n value: value,\n pos: pos\n };\n\n if ((pos += 5) > buf.length)\n throw RangeError('cannot read string length');\n\n return {\n value: value,\n pos: pos\n };\n}\n\nfunction recreateResultHyperlink(a) {\n var url = a.href;\n // remove AMP class, get actual page URL\n var ampCur = a.getAttribute('data-amp-cur');\n if (ampCur) {\n url = ampCur;\n a.classList.remove('amp_r');\n } else {\n var realLink = getRealLinkFromGoogleUrl(a);\n if (realLink) {\n url = realLink;\n } else {\n // might not be an actual hyperlink, ignore it\n if (!a.href) {\n return false;\n }\n // leave original href unchanged\n }\n }\n\n // re-create with original CSS classes\n replaceHyperlink(a, url);\n\n return true;\n}\n\nfunction isResult(a) {\n if (a.getAttribute('data-amp-cur'))\n return true;\n var inlineMousedown = a.getAttribute('onmousedown');\n if (!inlineMousedown)\n return false;\n // return rwt(....); // E.g Google search results.\n // return google.rwt(...); // E.g. sponsored search results\n // return google.arwt(this); // E.g. sponsored search results (dec 2016).\n return /\\ba?rwt\\(/.test(inlineMousedown) || /\\bctpacw\\b/.test(inlineMousedown);\n}\n\n/**\n * @returns {String} the real URL if the given link is a Google redirect URL.\n */\nfunction getRealLinkFromGoogleUrl(a) {\n if ((a.hostname === location.hostname || a.hostname.indexOf('www.google.') == 0) &&\n /^\\/(local_)?url$/.test(a.pathname)) {\n // Google Maps / Dito (/local_url?q=)\n // Mobile (/url?q=)\n var url = /[?&](?:q|url)=((?:https?|ftp)[%:][^&]+)/.exec(a.search);\n if (url)\n return decodeURIComponent(url[1]);\n // Help pages, e.g. safe browsing (/url?...&q=%2Fsupport%2Fanswer...)\n url = /[?&](?:q|url)=((?:%2[Ff]|\\/)[^&]+)/.exec(a.search);\n if (url)\n return a.origin + decodeURIComponent(url[1]);\n }\n}\n\nfunction sanitizeAds() {\n // scan all divs\n var div = document.getElementById('tads');\n if (div) {\n div.style.display = 'none';\n return true;\n }\n return false;\n}\n\nfunction sanitizeCards(rootNode) {\n var total = 0;\n var sanitized = 0;\n\n // fix cards\n rootNode.querySelectorAll('g-inner-card a').forEach(function(a) {\n total++;\n if (!a.sane && recreateResultHyperlink(a))\n sanitized++;\n });\n console.log(\"sanitized \", sanitized, \"/\", total, \" card hyperlinks\");\n}\n\nfunction hookMoreSearchResults() {\n var cardsFn = function(e) {\n var node = e.target;\n\n if (node.nodeName == '#text' && node.parentNode && node.parentNode.nodeName == 'TITLE') {\n // title is updated when page loading completes, thus trigger hyperlinks fixing afterwards\n sanitizeCards(document);\n document.removeEventListener('DOMNodeInserted', cardsFn);\n }\n }\n\n // detect and sanitize cards\n document.addEventListener('DOMNodeInserted', cardsFn);\n\n var extrares = document.getElementById('extrares');\n if (!extrares) {\n console.warn(\"could not hook more results\");\n return;\n }\n // mutation observers are great but they don't work\n extrares.addEventListener(\"DOMNodeInserted\", function(e) {\n var node = e.target;\n\n if (node.id && node.id.startsWith(\"arc-srp\"))\n sanitizeResultHyperlinks(node);\n });\n}\n\nfunction setMlogoClick() {\n // skip home page\n if (document.getElementById('hplogo')) return;\n\n var mlogo = document.getElementById('qslc');\n if (mlogo && mlogo.children[0]) {\n mlogo = mlogo.children[0];\n } else {\n mlogo = document.getElementById('mlogo');\n }\n if (mlogo) {\n mlogo.removeAttribute(\"href\");\n mlogo.setAttribute(\"onclick\", \"sanitizeAll()\");\n console.log(\"logo link replaced\");\n } else {\n console.warn(\"could not replace logo link\");\n }\n}\n\nfunction sanitizeResultHyperlinks(rootNode) {\n var sanitized = 0,\n total = 0;\n // exclude translation hyperlink nodes\n const exclude = rootNode.querySelectorAll('#tw-ob a');\n // selector for results (doesn't work with news anymore)\n rootNode.querySelectorAll('div[data-hveid]:not([data-hveid=\"\"]) a, div[data-ved]:not([data-ved=\"\"]) a').forEach(function(a) {\n // exclude nodes which should not be processed\n var excluded = false;\n exclude.forEach(function(e) {\n if (excluded) return;\n if (e == a) {\n excluded = true;\n }\n });\n if (excluded) return;\n\n total++;\n if (!a.sane && recreateResultHyperlink(a))\n sanitized++;\n });\n console.log(\"sanitized \", sanitized, \"/\", total, \" result hyperlinks\");\n}\n\nfunction sanitizeAllNews(rootNode) {\n var sanitized = 0,\n total = 0;\n // pick all articles which have the associated data not yet wiped\n rootNode.querySelectorAll('article[jsdata]:not([jsdata=\"\"]) a').forEach(function(a) {\n total++;\n if (!a.sane && recreateNewsHyperlink(a))\n sanitized++;\n });\n console.log(\"sanitized \", sanitized, \"/\", total, \" news hyperlinks\");\n}\n\nfunction hookMoreNews(rootNode) {\n var newsFn = function(e) {\n var node = e.target;\n // the real inserted node is 'C-WIZ', but we need to wait for loading to complete\n if (node.nodeName == '#text' && node.parentNode && node.parentNode.nodeName == 'TITLE') {\n // title is updated when page loading completes, thus trigger hyperlinks fixing afterwards\n sanitizeAllNews(rootNode);\n rootNode.removeEventListener('DOMNodeInserted', newsFn);\n }\n }\n rootNode.addEventListener('DOMNodeInserted', newsFn);\n}\n\nfunction hookMoreImageResults() {\n document.addEventListener(\"DOMNodeInserted\", function(e) {\n var node = e.target;\n // remove card and iframe, fix hyperlink\n if (node.nodeName == \"DIV\" && node.hasAttribute(\"data-query\"))\n sanitizeResultHyperlinks(node);\n else if (node.nodeName == \"IFRAME\")\n node.parentNode.removeChild(node);\n else if (node.nodeName == \"C-WIZ\")\n // replace instead of removing so that correlated image results will be displayed\n node.parentNode.replaceChild(node, document.createTextNode(\"iframe replaced\"));\n });\n}\n\nconsole.log('Bromite click-tracking and AMP removal v0.4.3');\n\nif (document.location.host.indexOf(\"news.google.\") === 0) {\n sanitizeAllNews(document);\n hookMoreNews(document);\n} else {\n // avoid running cleanup on non-result pages\n if (document.location.host.indexOf(\"accounts.google.\") == -1) {\n console.log(\"ads removed: \", sanitizeAds());\n\n if (document.location.search.match(/[?&]tbm=isch/)) {\n // find main c-wiz\n var cwizs = document.querySelectorAll('c-wiz[data-ssc=\"0\"]');\n if (cwizs.length)\n sanitizeResultHyperlinks(cwizs[0]);\n else\n console.warning('could not find main image results');\n // image search results\n hookMoreImageResults();\n } else {\n var main = document.getElementById('main');\n if (main)\n sanitizeResultHyperlinks(main);\n else\n console.warning('could not find main search results');\n // regular search results\n setMlogoClick();\n hookMoreSearchResults();\n }\n }\n}\n" + +#endif // anti_amp_cure_h diff --git a/third_party/blink/renderer/core/dom/extensions/video_bg_play.h b/third_party/blink/renderer/core/dom/extensions/video_bg_play.h @@ -146,7 +146,7 @@ new file mode 100644 +#ifndef video_bg_play_h +#define video_bg_play_h + -+#define VIDEO_BG_PLAY_JS "'use strict';\n\nconst IS_YOUTUBE = window.location.hostname.search(/(?:^|.+\\.)youtube.com/) > -1 ||\n window.location.hostname.search(/(?:^|.+\\.)youtube-nocookie.com/) > -1;\nconst IS_MOBILE_YOUTUBE = window.location.hostname == 'm.youtube.com';\nconst IS_VIMEO = window.location.hostname.search(/(?:^|.+\\.)vimeo.com/) > -1;\n\n/* video background play fix - based on https://github.com/mozilla/video-bg-play */\ndocument.wrappedJSObject = {};\n\n// Page Visibility API\nObject.defineProperties(document.wrappedJSObject,\n { 'hidden': {value: false}, 'visibilityState': {value: 'visible'} });\n\nwindow.addEventListener(\n 'visibilitychange', evt => evt.stopImmediatePropagation(), true);\n\n// Fullscreen API\nif (IS_VIMEO) {\n window.addEventListener(\n 'fullscreenchange', evt => evt.stopImmediatePropagation(), true);\n}\n\n// User activity tracking\nif (IS_YOUTUBE) {\n const refreshInterval = 2 + 3 * 60 * 1000; // every 3 minutes\n waitForYoutubeLactInit(() => refreshLact(), refreshInterval);\n}\n\nfunction waitForYoutubeLactInit(aCallback, aCallbackInterval, aDelay) {\n let pageWin = window.wrappedJSObject;\n if (pageWin.hasOwnProperty('_lact')) {\n window.setInterval(aCallback, aCallbackInterval);\n } else {\n window.setTimeout(() => waitForYoutubeLactInit(aCallback,\n aCallbackInterval,\n aDelay * 2),\n aDelay);\n }\n}\n\nfunction refreshLact() {\n window.wrappedJSObject._lact = Date.now();\n}\n" ++#define VIDEO_BG_PLAY_JS "'use strict';\n\nconst IS_YOUTUBE = window.location.hostname.search(/(?:^|.+\\.)youtube.com/) > -1 ||\n window.location.hostname.search(/(?:^|.+\\.)youtube-nocookie.com/) > -1;\nconst IS_MOBILE_YOUTUBE = window.location.hostname == 'm.youtube.com';\nconst IS_VIMEO = window.location.hostname.search(/(?:^|.+\\.)vimeo.com/) > -1;\n\n/* video background play fix - based on https://github.com/mozilla/video-bg-play */\ndocument.wrappedJSObject = {};\n\n// Page Visibility API\nObject.defineProperties(document.wrappedJSObject,\n { 'hidden': {value: false}, 'visibilityState': {value: 'visible'} });\n\nwindow.addEventListener(\n 'visibilitychange', evt => evt.stopImmediatePropagation(), true);\n\n// Fullscreen API\nif (IS_VIMEO) {\n window.addEventListener(\n 'fullscreenchange', evt => evt.stopImmediatePropagation(), true);\n}\n\n// User activity tracking\nif (IS_YOUTUBE) {\n const refreshInterval = 2 + 3 * 60 * 1000; // every 3 minutes\n waitForYoutubeLactInit(() => refreshLact(), refreshInterval);\n}\n\nfunction waitForYoutubeLactInit(aCallback, aCallbackInterval, aDelay) {\n let pageWin = document.wrappedJSObject;\n if (pageWin.hasOwnProperty('_lact')) {\n window.setInterval(aCallback, aCallbackInterval);\n } else {\n window.setTimeout(() => waitForYoutubeLactInit(aCallback,\n aCallbackInterval,\n aDelay * 2),\n aDelay);\n }\n}\n\nfunction refreshLact() {\n document.wrappedJSObject._lact = Date.now();\n}\n" + +#endif // video_bg_play_h diff --git a/third_party/blink/renderer/core/html/html_script_element.cc b/third_party/blink/renderer/core/html/html_script_element.cc diff --git a/build/patches/User-Agent-anonymize.patch b/build/patches/User-Agent-anonymize.patch deleted file mode 100644 index 6b7e8ff1..00000000 --- a/build/patches/User-Agent-anonymize.patch +++ /dev/null @@ -1,59 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Wed, 21 Mar 2018 14:15:28 +0100 -Subject: User Agent: anonymize - -Use a fixed device name and product version with the goal of not -disclosing the specific build of Bromite. ---- - components/version_info/version_info.cc | 3 ++- - content/common/user_agent.cc | 15 ++++----------- - 2 files changed, 6 insertions(+), 12 deletions(-) - -diff --git a/components/version_info/version_info.cc b/components/version_info/version_info.cc ---- a/components/version_info/version_info.cc -+++ b/components/version_info/version_info.cc -@@ -16,7 +16,8 @@ - namespace version_info { - - std::string GetProductNameAndVersionForUserAgent() { -- return "Chrome/" + GetVersionNumber(); -+ // latest stable version -+ return "Chrome/79.0.3945.136"; - } - - std::string GetProductName() { -diff --git a/content/common/user_agent.cc b/content/common/user_agent.cc ---- a/content/common/user_agent.cc -+++ b/content/common/user_agent.cc -@@ -87,7 +87,7 @@ std::string BuildOSCpuInfo(bool include_android_build_number) { - architecture_token = "; Win64; IA64"; - } - #elif defined(OS_ANDROID) -- std::string android_version_str = base::SysInfo::OperatingSystemVersion(); -+ std::string android_version_str = "9.0.0"; - std::string android_info_str = GetAndroidOSInfo(include_android_build_number); - #elif defined(OS_POSIX) && !defined(OS_MACOSX) - // Should work on any Posix system. -@@ -159,16 +159,9 @@ std::string BuildUserAgentFromProductAndExtraOSInfo( - } - - std::string GetAndroidOSInfo(bool include_android_build_number) { -- std::string android_info_str; -- -- // Send information about the device. -- bool semicolon_inserted = false; -- std::string android_build_codename = base::SysInfo::GetAndroidBuildCodename(); -- std::string android_device_name = base::SysInfo::HardwareModelName(); -- if (!android_device_name.empty() && "REL" == android_build_codename) { -- android_info_str += "; " + android_device_name; -- semicolon_inserted = true; -- } -+ // Send spoofed information about the device. -+ std::string android_info_str = "; SM-G955U"; -+ bool semicolon_inserted = true; - - // Append the build ID. - if (base::FeatureList::IsEnabled(kAndroidUserAgentStringContainsBuildId) || --- -2.17.1 -