From 1247ed0b6bd456d7125b80c595a4433f0697e5a0 Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 29 Jul 2021 09:53:49 +0200 Subject: [PATCH 1/8] Translated using Weblate (Japanese) Currently translated at 100.0% (1379 of 1379 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/ Translated using Weblate (Japanese) Currently translated at 99.9% (1378 of 1379 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/ --- www/common/translations/messages.ja.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/www/common/translations/messages.ja.json b/www/common/translations/messages.ja.json index 3d68dbab9..84fe9a3ae 100644 --- a/www/common/translations/messages.ja.json +++ b/www/common/translations/messages.ja.json @@ -560,7 +560,7 @@ "form_form": "フォーム", "form_editor": "エディタ", "form_delete": "削除", - "form_sent": "送信しました", + "form_sent": "回答を送信しました", "form_reset": "リセット", "form_update": "更新", "form_submit": "送信", @@ -1378,5 +1378,6 @@ "notification_linkShared": "{0}があなたとリンクを共有しました: {1}", "fm_link_name_placeholder": "あなたのリンク", "fm_link_warning": "注意:URLが200字を超えています", - "fm_link_invalid": "URLが無効です" + "fm_link_invalid": "URLが無効です", + "form_answerAs": "名前を記入してください" } From c6fefd73d846ae72eab8261a91ba1223d8148c34 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 30 Jul 2021 19:23:48 +0530 Subject: [PATCH 2/8] fix sheet conversion in Chrome by instantiating SharedArrayBuffers in a more portable way --- www/common/onlyoffice/inner.js | 25 ++++++++++++++++++++++++- www/common/onlyoffice/x2t/x2t.js | 15 ++++++++++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 4a0a56be0..5c57fbecc 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -72,8 +72,31 @@ define([ return JSONSortify(obj); }; + /* Chrome 92 dropped support for SharedArrayBuffer in cross-origin contexts + where window.crossOriginIsolated is false. + + Their blog (https://blog.chromium.org/2021/02/restriction-on-sharedarraybuffers.html) + isn't clear about why they're doing this, but since it's related to site-isolation + it seems they're trying to do vague security things. + + In any case, there seems to be a workaround where you can still create them + by using `new WebAssembly.Memory({shared: true, ...})` instead of `new SharedArrayBuffer`. + + This seems unreliable, but it's better than not being able to export, since + we actively rely on postMessage between iframes and therefore can't afford + to opt for full isolation. + */ + var supportsSharedArrayBuffers = function () { + try { + return Object.prototype.toString.call(new WebAssembly.Memory({shared: true, initial: 0, maximum: 0}).buffer) === '[object SharedArrayBuffer]'; + } catch (err) { + console.error(err); + } + return false; + }; + var supportsXLSX = function () { - return !(typeof(Atomics) === "undefined" || typeof (SharedArrayBuffer) === "undefined" || typeof(WebAssembly) === 'undefined'); + return !(typeof(Atomics) === "undefined" || !supportsSharedArrayBuffers() /* || typeof (SharedArrayBuffer) === "undefined" */ || typeof(WebAssembly) === 'undefined'); }; diff --git a/www/common/onlyoffice/x2t/x2t.js b/www/common/onlyoffice/x2t/x2t.js index 181b2db8f..9c1289c56 100644 --- a/www/common/onlyoffice/x2t/x2t.js +++ b/www/common/onlyoffice/x2t/x2t.js @@ -1,3 +1,8 @@ +function SUPPORTS_SHARED_MEMORY() { + return typeof(SharedArrayBuffer) !== 'undefined'; +} + + // Support for growable heap + pthreads, where the buffer may change, so JS views // must be updated. function GROWABLE_HEAP_STORE_I8(ptr, value) { @@ -1030,7 +1035,7 @@ if (ENVIRONMENT_IS_PTHREAD) { "maximum": 1073741824 / WASM_PAGE_SIZE, "shared": true }); - if (!(wasmMemory.buffer instanceof SharedArrayBuffer)) { + if (Object.prototype.toString.call(wasmMemory.buffer) !== '[object SharedArrayBuffer]') { err("requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag"); if (ENVIRONMENT_HAS_NODE) { console.log("(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and also use a recent version)"); @@ -2161,7 +2166,7 @@ var PThread = { }), receiveObjectTransfer: (function(data) {}), allocateUnusedWorkers: (function(numWorkers, onFinishedLoading) { - if (typeof SharedArrayBuffer === "undefined") return; + if (!SUPPORTS_SHARED_MEMORY()) return; var workers = []; var numWorkersToCreate = numWorkers; if (PThread.preallocatedWorkers.length > 0) { @@ -2276,7 +2281,7 @@ var PThread = { } }), createNewWorkers: (function(numWorkers) { - if (typeof SharedArrayBuffer === "undefined") return []; + if (!SUPPORTS_SHARED_MEMORY()) return []; var pthreadMainJs = "x2t.worker.js"; pthreadMainJs = locateFile(pthreadMainJs); var newWorkers = []; @@ -5683,7 +5688,7 @@ function _emscripten_get_sbrk_ptr() { } Module["_emscripten_get_sbrk_ptr"] = _emscripten_get_sbrk_ptr; function _emscripten_has_threading_support() { - return typeof SharedArrayBuffer !== "undefined"; + return SUPPORTS_SHARED_MEMORY(); } Module["_emscripten_has_threading_support"] = _emscripten_has_threading_support; function _emscripten_is_main_browser_thread() { @@ -6761,7 +6766,7 @@ function _pthread_self() { } Module["_pthread_self"] = _pthread_self; function _pthread_create(pthread_ptr, attr, start_routine, arg) { - if (typeof SharedArrayBuffer === "undefined") { + if (!SUPPORTS_SHARED_MEMORY()) { err("Current environment does not support SharedArrayBuffer, pthreads are not available!"); return 6; } From b6cc4ef8cf9fe447823cea18d1099f1347a61008 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 2 Aug 2021 17:36:51 +0530 Subject: [PATCH 3/8] test browser-dependent SharedArrayBuffer support in checkup include debugging information in final report for when browser vendors inevitably break APIs again --- www/checkup/app-checkup.less | 17 ++++++- www/checkup/checkup-tools.js | 36 +++++++++++++ www/checkup/main.js | 97 ++++++++++++++++++++++++++++++++++-- www/checkup/sandbox/main.js | 24 ++++++++- 4 files changed, 166 insertions(+), 8 deletions(-) create mode 100644 www/checkup/checkup-tools.js diff --git a/www/checkup/app-checkup.less b/www/checkup/app-checkup.less index a475d5983..df8cef8d8 100644 --- a/www/checkup/app-checkup.less +++ b/www/checkup/app-checkup.less @@ -14,11 +14,15 @@ html, body { .report { font-size: 30px; - max-width: 50%; + max-width: 26em; margin: auto; padding-top: 15px; } + .summary, .failure, .error, .success { + margin-bottom: 1em; + } + .pending { border: 1px solid @cryptpad_text_col; .fa { @@ -46,6 +50,10 @@ html, body { td { padding: 5px; border: 1px solid @cryptpad_text_col; + font-size: 60%; + } + td:nth-child(2) { + word-break: break-word; } } @@ -72,7 +80,12 @@ html, body { color: @cryptpad_color_link; } } - .cp-app-checkup-version { + + .cp-notice-browser, .cp-notice-details, .cp-notice-other { + font-size: 70%; + } + + .cp-app-checkup-version, .cp-app-checkup-browser { text-decoration: underline; } diff --git a/www/checkup/checkup-tools.js b/www/checkup/checkup-tools.js new file mode 100644 index 000000000..79fe1c4b3 --- /dev/null +++ b/www/checkup/checkup-tools.js @@ -0,0 +1,36 @@ +define([ +], function () { + var Tools = {}; + Tools.supportsSharedArrayBuffers = function () { + try { + return Object.prototype.toString.call(new window.WebAssembly.Memory({ + shared: true, + initial: 0, + maximum: 0, + }).buffer) === '[object SharedArrayBuffer]'; + } catch (err) { + console.error(err); + } + return false; + }; + + + Tools.isSafari = function () { + return navigator.vendor.match(/apple/i); + }; + + Tools.isChrome = function () { + return navigator.vendor.match(/google/i); + }; + + Tools.guessBrowser = function () { + if (Tools.isChrome()) { return 'chrome/blink'; } + if (Tools.isSafari()) { return 'safari/webkit'; } + if (navigator.userAgent.match(/firefox\//i)) { return 'firefox/gecko'; } + if (navigator.userAgent.match(/edge\//i)) { return 'edge/edgehtml'; } + if (navigator.userAgent.match(/trident\//i)) { return 'ie/trident'; } + return navigator.userAgent + "\n" + navigator.vendor; + }; + + return Tools; +}); diff --git a/www/checkup/main.js b/www/checkup/main.js index 4413d3b18..0addabaa2 100644 --- a/www/checkup/main.js +++ b/www/checkup/main.js @@ -13,13 +13,14 @@ define([ '/common/pinpad.js', '/common/outer/network-config.js', '/customize/pages.js', + '/checkup/checkup-tools.js', '/bower_components/tweetnacl/nacl-fast.min.js', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css', 'less!/checkup/app-checkup.less', ], function ($, ApiConfig, Assertions, h, Messages, DomReady, nThen, SFCommonO, Login, Hash, Util, Pinpad, - NetConfig, Pages) { + NetConfig, Pages, Tools) { var Assert = Assertions(); var trimSlashes = function (s) { if (typeof(s) !== 'string') { return s; } @@ -703,6 +704,81 @@ define([ }); }); + var safariGripe = function () { + return h('p.cp-notice-other', 'This is expected because Safari and platforms that use its engine lack commonly supported functionality.'); + }; + + var chromeGripe = function () { + return h('p.cp-notice-other', "This is expected because the developers of Google chrome's engine intentionally disabled support in cross-origin contexts. We are working on an alternate solution."); + }; + + var browserIssue = function () { + return h('p.cp-notice-other', 'This test checks for the presence of features in your browser and is not necessarily caused by server misconfiguration.'); + }; + + assert(function (cb, msg) { + cb = Util.once(cb); + setWarningClass(msg); + var notice = h('span', [ + h('p', 'It appears that some features required for Office file format conversion are not present.'), + ]); + + msg.appendChild(notice); + + var expected = [ + 'Atomics', + 'SharedArrayBuffer', + 'WebAssembly', + ['WebAssembly', 'Memory'], + ['WebAssembly', 'instantiate'], + ['WebAssembly', 'instantiateStreaming'], + ['Buffer', 'from'], + + 'SharedWorker', + 'worker', + 'crossOriginIsolated', + ]; + + var responses = {}; + + nThen(function (w) { + deferredPostMessage({ + command: 'CHECK_JS_APIS', + content: { + globals: expected, + }, + }, w(function (response) { + Util.extend(responses, response); + })); + + deferredPostMessage({ + command: 'FANCY_API_CHECKS', + content: { + }, + }, w(function (response) { + Util.extend(responses, response); + })); + }).nThen(function () { + if (!responses.Atomics || !responses.WebAssembly) { + return void cb(responses); + } + if (responses.SharedArrayBuffer || responses.SharedArrayBufferFallback) { + return cb(true); + } + + if (Tools.isSafari()) { + notice.appendChild(safariGripe()); + } + if (Tools.isChrome()) { + notice.appendChild(chromeGripe()); + } + + notice.appendChild(browserIssue()); + + return void cb(response); + }); + }); + var isHTTPS = function (host) { return /^https:\/\//.test(host); }; @@ -831,7 +907,7 @@ define([ var failureReport = function (obj) { var printableValue = obj.output; try { - printableValue = JSON.stringify(obj.output); + printableValue = JSON.stringify(obj.output, null, ' '); } catch (err) { console.error(err); } @@ -840,7 +916,7 @@ define([ h('h5', obj.message), h('table', [ row(["Failed test number", obj.test + 1]), - row(["Returned value", code(printableValue)]), + row(["Returned value", h('pre', code(printableValue))]), ]), ]); }; @@ -849,7 +925,7 @@ define([ var $progress = $('#cp-progress'); var versionStatement = function () { - return h('p', [ + return h('p.cp--notice-version', [ "This instance is running ", h('span.cp-app-checkup-version',[ "CryptPad", @@ -860,6 +936,16 @@ define([ ]); }; + var browserStatement = function () { + var name = Tools.guessBrowser(); + if (!name) { return; } + return h('p.cp-notice-browser', [ + "You appear to be using a ", + h('span.cp-app-checkup-browser', name), + ' browser to view this page.', + ]); + }; + Assert.run(function (state) { var errors = state.errors; var failed = errors.length; @@ -870,10 +956,11 @@ define([ var failedDetails = "Details found below"; var successDetails = "This checkup only tests the most common configuration issues. You may still experience errors or incorrect behaviour."; - var details = h('p', failed? failedDetails: successDetails); + var details = h('p.cp-notice-details', failed? failedDetails: successDetails); var summary = h('div.summary.' + statusClass, [ versionStatement(), + browserStatement(), h('p', Messages._getKey('assert_numberOfTestsPassed', [ state.passed, state.total diff --git a/www/checkup/sandbox/main.js b/www/checkup/sandbox/main.js index e11aa1d52..272db91a4 100644 --- a/www/checkup/sandbox/main.js +++ b/www/checkup/sandbox/main.js @@ -1,10 +1,12 @@ define([ 'jquery', + '/common/common-util.js', + '/checkup/checkup-tools.js', '/bower_components/tweetnacl/nacl-fast.min.js', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css', 'less!/checkup/app-checkup.less', -], function ($) { +], function ($, Util, Tools) { var postMessage = function (content) { window.parent.postMessage(JSON.stringify(content), '*'); }; @@ -26,6 +28,26 @@ define([ }); }; + COMMANDS.CHECK_JS_APIS = function (content, cb) { + var globalAPIs = content['globals'] || []; + var response = {}; + globalAPIs.forEach(function (key) { + if (Array.isArray(key)) { + response[key.join('.')] = Boolean(Util.find(window, key)); + return; + } + + response[key] = Boolean(window[key]); + }); + cb(response); + }; + + COMMANDS.FANCY_API_CHECKS = function (content, cb) { + cb({ + SharedArrayBufferFallback: Tools.supportsSharedArrayBuffers(), + }); + }; + window.addEventListener("message", function (event) { var txid, command; if (event && event.data) { From f4e2e505fe3f187d020f99f77dec433d744cfe61 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 2 Aug 2021 17:37:06 +0530 Subject: [PATCH 4/8] lint compliance --- www/common/onlyoffice/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 5c57fbecc..ff738e636 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -88,7 +88,7 @@ define([ */ var supportsSharedArrayBuffers = function () { try { - return Object.prototype.toString.call(new WebAssembly.Memory({shared: true, initial: 0, maximum: 0}).buffer) === '[object SharedArrayBuffer]'; + return Object.prototype.toString.call(new window.WebAssembly.Memory({shared: true, initial: 0, maximum: 0}).buffer) === '[object SharedArrayBuffer]'; } catch (err) { console.error(err); } From 613868bbdef43ba20dff938e5091dc2f492834d1 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 2 Aug 2021 17:59:53 +0530 Subject: [PATCH 5/8] fix safari-specific warnings in checkup --- www/checkup/main.js | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/www/checkup/main.js b/www/checkup/main.js index 0addabaa2..6fd085464 100644 --- a/www/checkup/main.js +++ b/www/checkup/main.js @@ -708,10 +708,6 @@ define([ return h('p.cp-notice-other', 'This is expected because Safari and platforms that use its engine lack commonly supported functionality.'); }; - var chromeGripe = function () { - return h('p.cp-notice-other', "This is expected because the developers of Google chrome's engine intentionally disabled support in cross-origin contexts. We are working on an alternate solution."); - }; - var browserIssue = function () { return h('p.cp-notice-other', 'This test checks for the presence of features in your browser and is not necessarily caused by server misconfiguration.'); }; @@ -721,6 +717,8 @@ define([ setWarningClass(msg); var notice = h('span', [ h('p', 'It appears that some features required for Office file format conversion are not present.'), + Tools.isSafari()? safariGripe(): undefined, + browserIssue(), ]); msg.appendChild(notice); @@ -765,16 +763,6 @@ define([ if (responses.SharedArrayBuffer || responses.SharedArrayBufferFallback) { return cb(true); } - - if (Tools.isSafari()) { - notice.appendChild(safariGripe()); - } - if (Tools.isChrome()) { - notice.appendChild(chromeGripe()); - } - - notice.appendChild(browserIssue()); - return void cb(response); }); }); From dd53b6fa72b917445013c59719e94a3a0d7ddc43 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 2 Aug 2021 18:05:46 +0530 Subject: [PATCH 6/8] constrain table width in checkup summaries --- www/checkup/app-checkup.less | 20 ++++++++++++-------- www/checkup/main.js | 10 ++++++---- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/www/checkup/app-checkup.less b/www/checkup/app-checkup.less index df8cef8d8..026d1952c 100644 --- a/www/checkup/app-checkup.less +++ b/www/checkup/app-checkup.less @@ -46,14 +46,18 @@ html, body { padding: 15px; } - table { - td { - padding: 5px; - border: 1px solid @cryptpad_text_col; - font-size: 60%; - } - td:nth-child(2) { - word-break: break-word; + .table-container { + overflow-x: auto; + width: 100%; + table { + td { + padding: 5px; + border: 1px solid @cryptpad_text_col; + font-size: 60%; + } + td:nth-child(2) { + word-break: break-word; + } } } diff --git a/www/checkup/main.js b/www/checkup/main.js index 6fd085464..171b9ac3b 100644 --- a/www/checkup/main.js +++ b/www/checkup/main.js @@ -902,10 +902,12 @@ define([ return h('div.error', [ h('h5', obj.message), - h('table', [ - row(["Failed test number", obj.test + 1]), - row(["Returned value", h('pre', code(printableValue))]), - ]), + h('div.table-container', + h('table', [ + row(["Failed test number", obj.test + 1]), + row(["Returned value", h('pre', code(printableValue))]), + ]), + ), ]); }; From ceab8fe2df09649d55b99d3f8ad08699e9582b84 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 2 Aug 2021 18:16:22 +0530 Subject: [PATCH 7/8] disable broken CSV export --- www/common/onlyoffice/inner.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index ff738e636..2afef4978 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -1938,7 +1938,9 @@ define([ var exportXLSXFile = function() { var text = getContent(); var suggestion = Title.suggestTitle(Title.defaultTitle); - var ext = ['.xlsx', '.ods', '.bin', '.csv', '.pdf']; + var ext = ['.xlsx', '.ods', '.bin', + //'.csv', // XXX + '.pdf']; var type = common.getMetadataMgr().getPrivateData().ooType; var warning = ''; if (type==="presentation") { From 7885a3ff5b3d6f21f14b5ff51f389eef6b2c948f Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 2 Aug 2021 19:55:19 +0530 Subject: [PATCH 8/8] update changelog with latest hotfixes --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23f48dc01..764a1f290 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# WIP + +* Sheet export + * most exports broken by Chrome 92, mostly fixed + * we discovered that CSV export was not working in any major browser, though it's unclear why. We've disabled CSV export in the meantime +* some new browser-specific checkup tests to make it easier to detect future regressions in the APIs needed for sheet export + # 4.9.0 ## Goals and announcements