From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/chat/protocols/xmpp/.eslintrc.js | 12 + comm/chat/protocols/xmpp/components.conf | 15 + comm/chat/protocols/xmpp/icons/prpl-jabber-32.png | Bin 0 -> 1725 bytes comm/chat/protocols/xmpp/icons/prpl-jabber-48.png | Bin 0 -> 2536 bytes comm/chat/protocols/xmpp/icons/prpl-jabber.png | Bin 0 -> 768 bytes comm/chat/protocols/xmpp/jar.mn | 5 + comm/chat/protocols/xmpp/lib/README.md | 6 + comm/chat/protocols/xmpp/lib/moz.build | 8 + comm/chat/protocols/xmpp/lib/sax/LICENSE | 41 + comm/chat/protocols/xmpp/lib/sax/sax.js | 1648 ++++++++++ comm/chat/protocols/xmpp/moz.build | 26 + comm/chat/protocols/xmpp/sax.sys.mjs | 7 + comm/chat/protocols/xmpp/test/test_authmechs.js | 160 + comm/chat/protocols/xmpp/test/test_dnsSrv.js | 112 + .../xmpp/test/test_parseJidAndNormalization.js | 104 + comm/chat/protocols/xmpp/test/test_parseVCard.js | 139 + comm/chat/protocols/xmpp/test/test_saslPrep.js | 66 + comm/chat/protocols/xmpp/test/test_xmppParser.js | 135 + comm/chat/protocols/xmpp/test/test_xmppXml.js | 103 + comm/chat/protocols/xmpp/test/xpcshell.ini | 11 + comm/chat/protocols/xmpp/xmpp-authmechs.sys.mjs | 561 ++++ comm/chat/protocols/xmpp/xmpp-base.sys.mjs | 3421 ++++++++++++++++++++ comm/chat/protocols/xmpp/xmpp-commands.sys.mjs | 347 ++ comm/chat/protocols/xmpp/xmpp-session.sys.mjs | 764 +++++ comm/chat/protocols/xmpp/xmpp-xml.sys.mjs | 508 +++ comm/chat/protocols/xmpp/xmpp.sys.mjs | 106 + 26 files changed, 8305 insertions(+) create mode 100644 comm/chat/protocols/xmpp/.eslintrc.js create mode 100644 comm/chat/protocols/xmpp/components.conf create mode 100644 comm/chat/protocols/xmpp/icons/prpl-jabber-32.png create mode 100644 comm/chat/protocols/xmpp/icons/prpl-jabber-48.png create mode 100644 comm/chat/protocols/xmpp/icons/prpl-jabber.png create mode 100644 comm/chat/protocols/xmpp/jar.mn create mode 100644 comm/chat/protocols/xmpp/lib/README.md create mode 100644 comm/chat/protocols/xmpp/lib/moz.build create mode 100644 comm/chat/protocols/xmpp/lib/sax/LICENSE create mode 100644 comm/chat/protocols/xmpp/lib/sax/sax.js create mode 100644 comm/chat/protocols/xmpp/moz.build create mode 100644 comm/chat/protocols/xmpp/sax.sys.mjs create mode 100644 comm/chat/protocols/xmpp/test/test_authmechs.js create mode 100644 comm/chat/protocols/xmpp/test/test_dnsSrv.js create mode 100644 comm/chat/protocols/xmpp/test/test_parseJidAndNormalization.js create mode 100644 comm/chat/protocols/xmpp/test/test_parseVCard.js create mode 100644 comm/chat/protocols/xmpp/test/test_saslPrep.js create mode 100644 comm/chat/protocols/xmpp/test/test_xmppParser.js create mode 100644 comm/chat/protocols/xmpp/test/test_xmppXml.js create mode 100644 comm/chat/protocols/xmpp/test/xpcshell.ini create mode 100644 comm/chat/protocols/xmpp/xmpp-authmechs.sys.mjs create mode 100644 comm/chat/protocols/xmpp/xmpp-base.sys.mjs create mode 100644 comm/chat/protocols/xmpp/xmpp-commands.sys.mjs create mode 100644 comm/chat/protocols/xmpp/xmpp-session.sys.mjs create mode 100644 comm/chat/protocols/xmpp/xmpp-xml.sys.mjs create mode 100644 comm/chat/protocols/xmpp/xmpp.sys.mjs (limited to 'comm/chat/protocols/xmpp') diff --git a/comm/chat/protocols/xmpp/.eslintrc.js b/comm/chat/protocols/xmpp/.eslintrc.js new file mode 100644 index 0000000000..66953c7e25 --- /dev/null +++ b/comm/chat/protocols/xmpp/.eslintrc.js @@ -0,0 +1,12 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +module.exports = { + rules: { + // The following rules will not be enabled currently. + complexity: "off", + }, +}; diff --git a/comm/chat/protocols/xmpp/components.conf b/comm/chat/protocols/xmpp/components.conf new file mode 100644 index 0000000000..83943f1a34 --- /dev/null +++ b/comm/chat/protocols/xmpp/components.conf @@ -0,0 +1,15 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +Classes = [ + { + 'cid': '{dde786d1-6f59-43d0-9bc8-b505a757fb30}', + 'contract_ids': ['@mozilla.org/chat/xmpp;1'], + 'esModule': 'resource:///modules/xmpp.sys.mjs', + 'constructor': 'XMPPProtocol', + 'categories': {'im-protocol-plugin': 'prpl-jabber'}, + }, +] diff --git a/comm/chat/protocols/xmpp/icons/prpl-jabber-32.png b/comm/chat/protocols/xmpp/icons/prpl-jabber-32.png new file mode 100644 index 0000000000..98897f75fb Binary files /dev/null and b/comm/chat/protocols/xmpp/icons/prpl-jabber-32.png differ diff --git a/comm/chat/protocols/xmpp/icons/prpl-jabber-48.png b/comm/chat/protocols/xmpp/icons/prpl-jabber-48.png new file mode 100644 index 0000000000..805820c565 Binary files /dev/null and b/comm/chat/protocols/xmpp/icons/prpl-jabber-48.png differ diff --git a/comm/chat/protocols/xmpp/icons/prpl-jabber.png b/comm/chat/protocols/xmpp/icons/prpl-jabber.png new file mode 100644 index 0000000000..bb04c6e6df Binary files /dev/null and b/comm/chat/protocols/xmpp/icons/prpl-jabber.png differ diff --git a/comm/chat/protocols/xmpp/jar.mn b/comm/chat/protocols/xmpp/jar.mn new file mode 100644 index 0000000000..1f7ac54abc --- /dev/null +++ b/comm/chat/protocols/xmpp/jar.mn @@ -0,0 +1,5 @@ +chat.jar: +% skin prpl-jabber classic/1.0 %skin/classic/prpl/xmpp/ + skin/classic/prpl/xmpp/icon32.png (icons/prpl-jabber-32.png) + skin/classic/prpl/xmpp/icon48.png (icons/prpl-jabber-48.png) + skin/classic/prpl/xmpp/icon.png (icons/prpl-jabber.png) diff --git a/comm/chat/protocols/xmpp/lib/README.md b/comm/chat/protocols/xmpp/lib/README.md new file mode 100644 index 0000000000..c813b5d070 --- /dev/null +++ b/comm/chat/protocols/xmpp/lib/README.md @@ -0,0 +1,6 @@ +This directory contains sax-js from https://github.com/isaacs/sax-js. Current version is v1.2.4. + +## Updating sax-js + +1. Download a release version from https://github.com/isaacs/sax-js. +2. Copy `lib/sax.js` from the git repo to `sax/sax.js` in this directory. diff --git a/comm/chat/protocols/xmpp/lib/moz.build b/comm/chat/protocols/xmpp/lib/moz.build new file mode 100644 index 0000000000..b4f1787145 --- /dev/null +++ b/comm/chat/protocols/xmpp/lib/moz.build @@ -0,0 +1,8 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXTRA_JS_MODULES.sax += [ + "sax/sax.js", +] diff --git a/comm/chat/protocols/xmpp/lib/sax/LICENSE b/comm/chat/protocols/xmpp/lib/sax/LICENSE new file mode 100644 index 0000000000..ccffa082c9 --- /dev/null +++ b/comm/chat/protocols/xmpp/lib/sax/LICENSE @@ -0,0 +1,41 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +==== + +`String.fromCodePoint` by Mathias Bynens used according to terms of MIT +License, as follows: + + Copyright Mathias Bynens + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/comm/chat/protocols/xmpp/lib/sax/sax.js b/comm/chat/protocols/xmpp/lib/sax/sax.js new file mode 100644 index 0000000000..564d8d4235 --- /dev/null +++ b/comm/chat/protocols/xmpp/lib/sax/sax.js @@ -0,0 +1,1648 @@ +/* This program is made available under an ISC-style license. */ +(function(sax) { + // wrapper for non-node envs + sax.parser = function(strict, opt) { + return new SAXParser(strict, opt); + }; + sax.SAXParser = SAXParser; + sax.SAXStream = SAXStream; + sax.createStream = createStream; + + // When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns. + // When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)), + // since that's the earliest that a buffer overrun could occur. This way, checks are + // as rare as required, but as often as necessary to ensure never crossing this bound. + // Furthermore, buffers are only tested at most once per write(), so passing a very + // large string into write() might have undesirable effects, but this is manageable by + // the caller, so it is assumed to be safe. Thus, a call to write() may, in the extreme + // edge case, result in creating at most one complete copy of the string passed in. + // Set to Infinity to have unlimited buffers. + sax.MAX_BUFFER_LENGTH = 64 * 1024; + + var buffers = [ + "comment", + "sgmlDecl", + "textNode", + "tagName", + "doctype", + "procInstName", + "procInstBody", + "entity", + "attribName", + "attribValue", + "cdata", + "script", + ]; + + sax.EVENTS = [ + "text", + "processinginstruction", + "sgmldeclaration", + "doctype", + "comment", + "opentagstart", + "attribute", + "opentag", + "closetag", + "opencdata", + "cdata", + "closecdata", + "error", + "end", + "ready", + "script", + "opennamespace", + "closenamespace", + ]; + + function SAXParser(strict, opt) { + if (!(this instanceof SAXParser)) { + return new SAXParser(strict, opt); + } + + var parser = this; + clearBuffers(parser); + parser.q = parser.c = ""; + parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH; + parser.opt = opt || {}; + parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags; + parser.looseCase = parser.opt.lowercase ? "toLowerCase" : "toUpperCase"; + parser.tags = []; + parser.closed = parser.closedRoot = parser.sawRoot = false; + parser.tag = parser.error = null; + parser.strict = !!strict; + parser.noscript = !!(strict || parser.opt.noscript); + parser.state = S.BEGIN; + parser.strictEntities = parser.opt.strictEntities; + parser.ENTITIES = parser.strictEntities + ? Object.create(sax.XML_ENTITIES) + : Object.create(sax.ENTITIES); + parser.attribList = []; + + // namespaces form a prototype chain. + // it always points at the current tag, + // which protos to its parent tag. + if (parser.opt.xmlns) { + parser.ns = Object.create(rootNS); + } + + // mostly just for error reporting + parser.trackPosition = parser.opt.position !== false; + if (parser.trackPosition) { + parser.position = parser.line = parser.column = 0; + } + emit(parser, "onready"); + } + + if (!Object.create) { + Object.create = function(o) { + function F() {} + F.prototype = o; + var newf = new F(); + return newf; + }; + } + + if (!Object.keys) { + Object.keys = function(o) { + var a = []; + for (var i in o) { + if (o.hasOwnProperty(i)) { + a.push(i); + } + } + return a; + }; + } + + function checkBufferLength(parser) { + var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10); + var maxActual = 0; + for (var i = 0, l = buffers.length; i < l; i++) { + var len = parser[buffers[i]].length; + if (len > maxAllowed) { + // Text/cdata nodes can get big, and since they're buffered, + // we can get here under normal conditions. + // Avoid issues by emitting the text node now, + // so at least it won't get any bigger. + switch (buffers[i]) { + case "textNode": + closeText(parser); + break; + + case "cdata": + emitNode(parser, "oncdata", parser.cdata); + parser.cdata = ""; + break; + + case "script": + emitNode(parser, "onscript", parser.script); + parser.script = ""; + break; + + default: + error(parser, "Max buffer length exceeded: " + buffers[i]); + } + } + maxActual = Math.max(maxActual, len); + } + // schedule the next check for the earliest possible buffer overrun. + var m = sax.MAX_BUFFER_LENGTH - maxActual; + parser.bufferCheckPosition = m + parser.position; + } + + function clearBuffers(parser) { + for (var i = 0, l = buffers.length; i < l; i++) { + parser[buffers[i]] = ""; + } + } + + function flushBuffers(parser) { + closeText(parser); + if (parser.cdata !== "") { + emitNode(parser, "oncdata", parser.cdata); + parser.cdata = ""; + } + if (parser.script !== "") { + emitNode(parser, "onscript", parser.script); + parser.script = ""; + } + } + + SAXParser.prototype = { + end() { + end(this); + }, + write, + resume() { + this.error = null; + return this; + }, + close() { + return this.write(null); + }, + flush() { + flushBuffers(this); + }, + }; + + var Stream; + try { + Stream = require("stream").Stream; + } catch (ex) { + Stream = function() {}; + } + + var streamWraps = sax.EVENTS.filter(function(ev) { + return ev !== "error" && ev !== "end"; + }); + + function createStream(strict, opt) { + return new SAXStream(strict, opt); + } + + function SAXStream(strict, opt) { + if (!(this instanceof SAXStream)) { + return new SAXStream(strict, opt); + } + + Stream.apply(this); + + this._parser = new SAXParser(strict, opt); + this.writable = true; + this.readable = true; + + var me = this; + + this._parser.onend = function() { + me.emit("end"); + }; + + this._parser.onerror = function(er) { + me.emit("error", er); + + // if didn't throw, then means error was handled. + // go ahead and clear error, so we can write again. + me._parser.error = null; + }; + + this._decoder = null; + + streamWraps.forEach(function(ev) { + Object.defineProperty(me, "on" + ev, { + get() { + return me._parser["on" + ev]; + }, + set(h) { + if (!h) { + me.removeAllListeners(ev); + me._parser["on" + ev] = h; + return h; + } + me.on(ev, h); + }, + enumerable: true, + configurable: false, + }); + }); + } + + SAXStream.prototype = Object.create(Stream.prototype, { + constructor: { + value: SAXStream, + }, + }); + + SAXStream.prototype.write = function(data) { + if ( + typeof Buffer === "function" && + typeof Buffer.isBuffer === "function" && + Buffer.isBuffer(data) + ) { + if (!this._decoder) { + var SD = require("string_decoder").StringDecoder; + this._decoder = new SD("utf8"); + } + data = this._decoder.write(data); + } + + this._parser.write(data.toString()); + this.emit("data", data); + return true; + }; + + SAXStream.prototype.end = function(chunk) { + if (chunk && chunk.length) { + this.write(chunk); + } + this._parser.end(); + return true; + }; + + SAXStream.prototype.on = function(ev, handler) { + var me = this; + if (!me._parser["on" + ev] && streamWraps.indexOf(ev) !== -1) { + me._parser["on" + ev] = function() { + var args = + arguments.length === 1 + ? [arguments[0]] + : Array.apply(null, arguments); + args.splice(0, 0, ev); + me.emit.apply(me, args); + }; + } + + return Stream.prototype.on.call(me, ev, handler); + }; + + // this really needs to be replaced with character classes. + // XML allows all manner of ridiculous numbers and digits. + var CDATA = "[CDATA["; + var DOCTYPE = "DOCTYPE"; + var XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace"; + var XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/"; + var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE }; + + // http://www.w3.org/TR/REC-xml/#NT-NameStartChar + // This implementation works on strings, a single character at a time + // as such, it cannot ever support astral-plane characters (10000-EFFFF) + // without a significant breaking change to either this parser, or the + // JavaScript language. Implementation of an emoji-capable xml parser + // is left as an exercise for the reader. + var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; + + var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/; + + var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/; + var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/; + + function isWhitespace(c) { + return c === " " || c === "\n" || c === "\r" || c === "\t"; + } + + function isQuote(c) { + return c === '"' || c === "'"; + } + + function isAttribEnd(c) { + return c === ">" || isWhitespace(c); + } + + function isMatch(regex, c) { + return regex.test(c); + } + + function notMatch(regex, c) { + return !isMatch(regex, c); + } + + var S = 0; + sax.STATE = { + BEGIN: S++, // leading byte order mark or whitespace + BEGIN_WHITESPACE: S++, // leading whitespace + TEXT: S++, // general stuff + TEXT_ENTITY: S++, // & and such. + OPEN_WAKA: S++, // < + SGML_DECL: S++, // + SCRIPT: S++, //