diff -Nru thunderbird-91.7.0+build2/browser/components/extensions/parent/ext-chrome-settings-overrides.js thunderbird-91.8.1+build1/browser/components/extensions/parent/ext-chrome-settings-overrides.js
--- thunderbird-91.7.0+build2/browser/components/extensions/parent/ext-chrome-settings-overrides.js 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/extensions/parent/ext-chrome-settings-overrides.js 2022-04-15 07:40:51.000000000 +0000
@@ -339,7 +339,9 @@
extension.startupReason
);
}
- if (disable && item?.enabled) {
+ // Ensure the item is disabled. If addSetting was called above,
+ // Item may be null, and enabled may be undefined.
+ if (disable && item?.enabled !== false) {
item = await ExtensionSettingsStore.disable(
extension.id,
DEFAULT_SEARCH_STORE_TYPE,
@@ -367,7 +369,10 @@
// This is a hack because we don't have the browser of
// the actual install. This means the popup might show
// in a different window. Will be addressed in a followup bug.
- browser: windowTracker.topWindow.gBrowser.selectedBrowser,
+ // As well, we still notify if no topWindow exists to support
+ // testing from xpcshell.
+ browser: windowTracker.topWindow?.gBrowser.selectedBrowser,
+ id: extension.id,
name: extension.name,
icon: extension.iconURL,
currentEngine: defaultEngine.name,
@@ -476,7 +481,7 @@
Services.search.defaultEngine = Services.search.getEngineByName(
engineName
);
- } else {
+ } else if (extension.startupReason == "ADDON_ENABLE") {
// This extension has precedence, but is not in control. Ask the user.
await this.promptDefaultSearch(engineName);
}
diff -Nru thunderbird-91.7.0+build2/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload_smoketest.js thunderbird-91.8.1+build1/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload_smoketest.js
--- thunderbird-91.7.0+build2/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload_smoketest.js 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/extensions/test/browser/browser_ext_browserAction_popup_preload_smoketest.js 2022-04-15 07:40:52.000000000 +0000
@@ -0,0 +1,198 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+"use strict";
+
+// This test does create and cancel the preloaded popup
+// multiple times and in some cases it takes longer than
+// the default timeouts allows.
+requestLongerTimeout(4);
+
+const { AddonTestUtils } = ChromeUtils.import(
+ "resource://testing-common/AddonTestUtils.jsm"
+);
+
+async function installTestAddon(addonId, unpacked = false) {
+ let xpi = AddonTestUtils.createTempWebExtensionFile({
+ manifest: {
+ browser_specific_settings: { gecko: { id: addonId } },
+ browser_action: {
+ default_popup: "popup.html",
+ },
+ },
+ files: {
+ "popup.html": `
+
+
+
+
+
+
+
+
+ `,
+ "popup.css": `@import "imported.css";`,
+ "imported.css": `
+ /* Increasing the imported.css file size to increase the
+ * chances to trigger the stylesheet preload issue that
+ * has been fixed by Bug 1735899 consistently and with
+ * a smaller number of preloaded popup cancelled.
+ *
+ * ${new Array(600000).fill("x").join("\n")}
+ */
+ body { width: 300px; height: 300px; background: red; }
+ `,
+ },
+ });
+
+ if (unpacked) {
+ // This temporary directory is going to be removed from the
+ // cleanup function, but also make it unique as we do for the
+ // other temporary files (e.g. like getTemporaryFile as defined
+ // in XPInstall.jsm).
+ const random = Math.round(Math.random() * 36 ** 3).toString(36);
+ const tmpDirName = `mochitest_unpacked_addons_${random}`;
+ let tmpExtPath = FileUtils.getDir("TmpD", [tmpDirName], true);
+ registerCleanupFunction(() => {
+ tmpExtPath.remove(true);
+ });
+
+ // Unpacking the xpi file into the tempoary directory.
+ const extDir = await AddonTestUtils.manuallyInstall(
+ xpi,
+ tmpExtPath,
+ null,
+ /* unpacked */ true
+ );
+
+ // Install temporarily as unpacked.
+ return AddonManager.installTemporaryAddon(extDir);
+ }
+
+ // Install temporarily as packed.
+ return AddonManager.installTemporaryAddon(xpi);
+}
+
+async function waitForExtensionAndBrowserAction(addonId) {
+ const {
+ Management: {
+ global: { browserActionFor },
+ },
+ } = ChromeUtils.import("resource://gre/modules/Extension.jsm");
+
+ // trigger a number of preloads
+ let extension;
+ let browserAction;
+ await TestUtils.waitForCondition(() => {
+ extension = WebExtensionPolicy.getByID(addonId)?.extension;
+ browserAction = extension && browserActionFor(extension);
+ return browserAction;
+ }, "got the extension and browserAction");
+
+ let widget = getBrowserActionWidget(extension).forWindow(window);
+
+ return { extension, browserAction, widget };
+}
+
+async function testCancelPreloadedPopup({ browserAction, widget }) {
+ // Trigger the preloaded popup.
+ EventUtils.synthesizeMouseAtCenter(
+ widget.node,
+ { type: "mouseover", button: 0 },
+ window
+ );
+ await TestUtils.waitForCondition(
+ () => browserAction.pendingPopup,
+ "Wait for the preloaded popup"
+ );
+ // Cancel the preloaded popup.
+ EventUtils.synthesizeMouseAtCenter(
+ widget.node,
+ { type: "mouseout", button: 0 },
+ window
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ window.gURLBar.textbox,
+ { type: "mouseover" },
+ window
+ );
+ await TestUtils.waitForCondition(
+ () => !browserAction.pendingPopup,
+ "Wait for the preloaded popup to be cancelled"
+ );
+}
+
+async function testPopupLoadCompleted({ extension, browserAction, widget }) {
+ const promiseViewShowing = BrowserTestUtils.waitForEvent(
+ document,
+ "ViewShowing",
+ false,
+ ev => ev.target.id === browserAction.viewId
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ widget.node,
+ { type: "mousedown", button: 0 },
+ window
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ widget.node,
+ { type: "mouseup", button: 0 },
+ window
+ );
+
+ info("Await the browserAction popup to be shown");
+ await promiseViewShowing;
+
+ info("Await the browserAction popup to be fully loaded");
+ const browser = await awaitExtensionPanel(
+ extension,
+ window,
+ /* awaitLoad */ true
+ );
+
+ await TestUtils.waitForCondition(async () => {
+ const docReadyState = await SpecialPowers.spawn(browser, [], () => {
+ return this.content.document.readyState;
+ });
+
+ return docReadyState === "complete";
+ }, "Wait the popup document to get to readyState complete");
+
+ ok(true, "Popup document was fully loaded");
+}
+
+// This test is covering a scenario similar to the one fixed in Bug 1735899,
+// and possibly some other similar ones that may slip through unnoticed.
+add_task(async function testCancelPopupPreloadRaceOnUnpackedAddon() {
+ const ID = "preloaded-popup@test";
+ const addon = await installTestAddon(ID, /* unpacked */ true);
+ const {
+ extension,
+ browserAction,
+ widget,
+ } = await waitForExtensionAndBrowserAction(ID);
+ info("Preload popup and cancel it multiple times");
+ for (let i = 0; i < 200; i++) {
+ await testCancelPreloadedPopup({ browserAction, widget });
+ }
+ await testPopupLoadCompleted({ extension, browserAction, widget });
+ await addon.uninstall();
+});
+
+// This test is covering a scenario similar to the one fixed in Bug 1735899,
+// and possibly some other similar ones that may slip through unnoticed.
+add_task(async function testCancelPopupPreloadRaceOnPackedAddon() {
+ const ID = "preloaded-popup@test";
+ const addon = await installTestAddon(ID, /* unpacked */ false);
+ const {
+ extension,
+ browserAction,
+ widget,
+ } = await waitForExtensionAndBrowserAction(ID);
+ info("Preload popup and cancel it multiple times");
+ for (let i = 0; i < 200; i++) {
+ await testCancelPreloadedPopup({ browserAction, widget });
+ }
+ await testPopupLoadCompleted({ extension, browserAction, widget });
+ await addon.uninstall();
+});
diff -Nru thunderbird-91.7.0+build2/browser/components/extensions/test/browser/browser.ini thunderbird-91.8.1+build1/browser/components/extensions/test/browser/browser.ini
--- thunderbird-91.7.0+build2/browser/components/extensions/test/browser/browser.ini 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/extensions/test/browser/browser.ini 2022-04-15 07:40:51.000000000 +0000
@@ -69,6 +69,8 @@
[browser_ext_browserAction_popup_port.js]
[browser_ext_browserAction_popup_preload.js]
skip-if = (os == 'win' && !debug) || (verify && debug && (os == 'mac')) # bug 1352668
+[browser_ext_browserAction_popup_preload_smoketest.js]
+skip-if = debug # Bug 1746047
[browser_ext_browserAction_popup_resize.js]
[browser_ext_browserAction_popup_resize_bottom.js]
skip-if = debug # Bug 1522164
diff -Nru thunderbird-91.7.0+build2/browser/components/extensions/test/xpcshell/test_ext_chrome_settings_overrides_update.js thunderbird-91.8.1+build1/browser/components/extensions/test/xpcshell/test_ext_chrome_settings_overrides_update.js
--- thunderbird-91.7.0+build2/browser/components/extensions/test/xpcshell/test_ext_chrome_settings_overrides_update.js 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/extensions/test/xpcshell/test_ext_chrome_settings_overrides_update.js 2022-04-15 07:40:51.000000000 +0000
@@ -6,7 +6,9 @@
"resource://testing-common/AddonTestUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
+ AddonManager: "resource://gre/modules/AddonManager.jsm",
HomePage: "resource:///modules/HomePage.jsm",
+ PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
RemoteSettings: "resource://services-settings/remote-settings.js",
sinon: "resource://testing-common/Sinon.jsm",
});
@@ -24,6 +26,29 @@
// search service needs it.
Services.prefs.clearUserPref("services.settings.default_bucket");
+// Similar to TestUtils.topicObserved, but returns a deferred promise that
+// can be resolved
+function topicObservable(topic, checkFn) {
+ let deferred = PromiseUtils.defer();
+ function observer(subject, topic, data) {
+ try {
+ if (checkFn && !checkFn(subject, data)) {
+ return;
+ }
+ deferred.resolve([subject, data]);
+ } catch (ex) {
+ deferred.reject(ex);
+ }
+ }
+ deferred.promise.finally(() => {
+ Services.obs.removeObserver(observer, topic);
+ checkFn = null;
+ });
+ Services.obs.addObserver(observer, topic);
+
+ return deferred;
+}
+
async function setupRemoteSettings() {
const settings = await RemoteSettings("hijack-blocklists");
sinon.stub(settings, "get").returns([
@@ -50,7 +75,7 @@
/* This tests the scenario where the manifest key for homepage and/or
* search_provider are removed between updates and therefore the
* settings are expected to revert. It also tests that an extension
- * can make a builtin extension the default extension without user
+ * can make a builtin extension the default search without user
* interaction. */
const EXTENSION_ID = "test_overrides_update@tests.mozilla.org";
@@ -82,7 +107,20 @@
ok(defaultEngineName !== "DuckDuckGo", "Default engine is not DuckDuckGo.");
let prefPromise = promisePrefChanged(HOMEPAGE_URI);
- await extension.startup();
+
+ // When an addon is installed that overrides an app-provided engine (builtin)
+ // that is the default, we do not prompt for default.
+ let deferredPrompt = topicObservable(
+ "webextension-defaultsearch-prompt",
+ (subject, message) => {
+ if (subject.wrappedJSObject.id == extension.id) {
+ ok(false, "default override should not prompt");
+ }
+ }
+ );
+
+ await Promise.race([extension.startup(), deferredPrompt.promise]);
+ deferredPrompt.resolve();
await AddonTestUtils.waitForSearchProviderStartup(extension);
await prefPromise;
@@ -197,7 +235,21 @@
};
let prefPromise = promisePrefChanged(HOMEPAGE_URI);
- await extension.upgrade(extensionInfo);
+
+ let deferredUpgradePrompt = topicObservable(
+ "webextension-defaultsearch-prompt",
+ (subject, message) => {
+ if (subject.wrappedJSObject.id == extension.id) {
+ ok(false, "should not prompt on update");
+ }
+ }
+ );
+
+ await Promise.race([
+ extension.upgrade(extensionInfo),
+ deferredUpgradePrompt.promise,
+ ]);
+ deferredUpgradePrompt.resolve();
await AddonTestUtils.waitForSearchProviderStartup(extension);
await prefPromise;
@@ -286,4 +338,131 @@
);
await extension.unload();
+});
+
+add_task(async function test_default_search_prompts() {
+ /* This tests the scenario where an addon did not gain
+ * default search during install, and later upgrades.
+ * The addon should not gain default in updates.
+ * If the addon is disabled, it should prompt again when
+ * enabled.
+ */
+
+ const EXTENSION_ID = "test_default_update@tests.mozilla.org";
+
+ let extensionInfo = {
+ useAddonManager: "permanent",
+ manifest: {
+ version: "1.0",
+ applications: {
+ gecko: {
+ id: EXTENSION_ID,
+ },
+ },
+ chrome_settings_overrides: {
+ search_provider: {
+ name: "Example",
+ search_url: "https://example.com/?q={searchTerms}",
+ is_default: true,
+ },
+ },
+ },
+ };
+
+ let extension = ExtensionTestUtils.loadExtension(extensionInfo);
+
+ // Mock a response from the default search prompt where we
+ // say no to setting this as the default when installing.
+ let prompted = TestUtils.topicObserved(
+ "webextension-defaultsearch-prompt",
+ (subject, message) => {
+ if (subject.wrappedJSObject.id == extension.id) {
+ return subject.wrappedJSObject.respond(false);
+ }
+ }
+ );
+
+ let defaultEngineName = (await Services.search.getDefault()).name;
+ ok(defaultEngineName !== "Example", "Search is not Example.");
+
+ await extension.startup();
+ await prompted;
+
+ equal(
+ extension.version,
+ "1.0",
+ "The installed addon has the expected version."
+ );
+ equal(
+ (await Services.search.getDefault()).name,
+ defaultEngineName,
+ "Default engine is the default after startup."
+ );
+
+ extensionInfo.manifest = {
+ version: "2.0",
+ applications: {
+ gecko: {
+ id: EXTENSION_ID,
+ },
+ },
+ chrome_settings_overrides: {
+ search_provider: {
+ name: "Example",
+ search_url: "https://example.com/?q={searchTerms}",
+ is_default: true,
+ },
+ },
+ };
+
+ let deferredUpgradePrompt = topicObservable(
+ "webextension-defaultsearch-prompt",
+ (subject, message) => {
+ if (subject.wrappedJSObject.id == extension.id) {
+ ok(false, "should not prompt on update");
+ }
+ }
+ );
+
+ await Promise.race([
+ extension.upgrade(extensionInfo),
+ deferredUpgradePrompt.promise,
+ ]);
+ deferredUpgradePrompt.resolve();
+
+ await AddonTestUtils.waitForSearchProviderStartup(extension);
+
+ equal(
+ extension.version,
+ "2.0",
+ "The updated addon has the expected version."
+ );
+ // An upgraded extension does not become the default engine.
+ equal(
+ (await Services.search.getDefault()).name,
+ defaultEngineName,
+ "Default engine is still the default after startup."
+ );
+
+ let addon = await AddonManager.getAddonByID(EXTENSION_ID);
+ await addon.disable();
+
+ prompted = TestUtils.topicObserved(
+ "webextension-defaultsearch-prompt",
+ (subject, message) => {
+ if (subject.wrappedJSObject.id == extension.id) {
+ return subject.wrappedJSObject.respond(false);
+ }
+ }
+ );
+ await Promise.all([addon.enable(), prompted]);
+
+ // we still said no.
+ equal(
+ (await Services.search.getDefault()).name,
+ defaultEngineName,
+ "Default engine is the default after startup."
+ );
+
+ await extension.unload();
});
diff -Nru thunderbird-91.7.0+build2/browser/components/search/content/searchbar.js thunderbird-91.8.1+build1/browser/components/search/content/searchbar.js
--- thunderbird-91.7.0+build2/browser/components/search/content/searchbar.js 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/search/content/searchbar.js 2022-04-15 07:40:52.000000000 +0000
@@ -807,10 +807,11 @@
};
this.textbox.onkeyup = event => {
- if (
- event.keyCode === KeyEvent.DOM_VK_RETURN &&
- this._needBrowserFocusAtEnterKeyUp
- ) {
+ // Pressing Enter key while pressing Meta key, and next, even when
+ // releasing Enter key before releasing Meta key, the keyup event is not
+ // fired. Therefore, if Enter keydown is detecting, continue the post
+ // processing for Enter key when any keyup event is detected.
+ if (this._needBrowserFocusAtEnterKeyUp) {
this._needBrowserFocusAtEnterKeyUp = false;
gBrowser.selectedBrowser.focus();
}
diff -Nru thunderbird-91.7.0+build2/browser/components/search/extensions/google/_locales/region-by/messages.json thunderbird-91.8.1+build1/browser/components/search/extensions/google/_locales/region-by/messages.json
--- thunderbird-91.7.0+build2/browser/components/search/extensions/google/_locales/region-by/messages.json 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/search/extensions/google/_locales/region-by/messages.json 2022-04-15 07:40:52.000000000 +0000
@@ -0,0 +1,20 @@
+{
+ "extensionName": {
+ "message": "Google"
+ },
+ "extensionDescription": {
+ "message": "Google Search"
+ },
+ "searchUrl": {
+ "message": "https://www.google.by/search"
+ },
+ "searchForm": {
+ "message": "https://www.google.by/search?q={searchTerms}"
+ },
+ "suggestUrl": {
+ "message": "https://www.google.by/complete/search?client=firefox&q={searchTerms}"
+ },
+ "searchUrlGetParams": {
+ "message": "q={searchTerms}"
+ }
+}
diff -Nru thunderbird-91.7.0+build2/browser/components/search/extensions/google/_locales/region-kz/messages.json thunderbird-91.8.1+build1/browser/components/search/extensions/google/_locales/region-kz/messages.json
--- thunderbird-91.7.0+build2/browser/components/search/extensions/google/_locales/region-kz/messages.json 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/search/extensions/google/_locales/region-kz/messages.json 2022-04-15 07:40:52.000000000 +0000
@@ -0,0 +1,20 @@
+{
+ "extensionName": {
+ "message": "Google"
+ },
+ "extensionDescription": {
+ "message": "Google Search"
+ },
+ "searchUrl": {
+ "message": "https://www.google.kz/search"
+ },
+ "searchForm": {
+ "message": "https://www.google.kz/search?q={searchTerms}"
+ },
+ "suggestUrl": {
+ "message": "https://www.google.kz/complete/search?client=firefox&q={searchTerms}"
+ },
+ "searchUrlGetParams": {
+ "message": "q={searchTerms}"
+ }
+}
diff -Nru thunderbird-91.7.0+build2/browser/components/search/extensions/google/_locales/region-ru/messages.json thunderbird-91.8.1+build1/browser/components/search/extensions/google/_locales/region-ru/messages.json
--- thunderbird-91.7.0+build2/browser/components/search/extensions/google/_locales/region-ru/messages.json 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/search/extensions/google/_locales/region-ru/messages.json 2022-04-15 07:40:52.000000000 +0000
@@ -0,0 +1,20 @@
+{
+ "extensionName": {
+ "message": "Google"
+ },
+ "extensionDescription": {
+ "message": "Google Search"
+ },
+ "searchUrl": {
+ "message": "https://www.google.ru/search"
+ },
+ "searchForm": {
+ "message": "https://www.google.ru/search?q={searchTerms}"
+ },
+ "suggestUrl": {
+ "message": "https://www.google.ru/complete/search?client=firefox&q={searchTerms}"
+ },
+ "searchUrlGetParams": {
+ "message": "q={searchTerms}"
+ }
+}
diff -Nru thunderbird-91.7.0+build2/browser/components/search/extensions/google/_locales/region-tr/messages.json thunderbird-91.8.1+build1/browser/components/search/extensions/google/_locales/region-tr/messages.json
--- thunderbird-91.7.0+build2/browser/components/search/extensions/google/_locales/region-tr/messages.json 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/search/extensions/google/_locales/region-tr/messages.json 2022-04-15 07:40:52.000000000 +0000
@@ -0,0 +1,20 @@
+{
+ "extensionName": {
+ "message": "Google"
+ },
+ "extensionDescription": {
+ "message": "Google Search"
+ },
+ "searchUrl": {
+ "message": "https://www.google.com.tr/search"
+ },
+ "searchForm": {
+ "message": "https://www.google.com.tr/search?q={searchTerms}"
+ },
+ "suggestUrl": {
+ "message": "https://www.google.com.tr/complete/search?client=firefox&q={searchTerms}"
+ },
+ "searchUrlGetParams": {
+ "message": "q={searchTerms}"
+ }
+}
diff -Nru thunderbird-91.7.0+build2/browser/components/search/extensions/google/manifest.json thunderbird-91.8.1+build1/browser/components/search/extensions/google/manifest.json
--- thunderbird-91.7.0+build2/browser/components/search/extensions/google/manifest.json 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/search/extensions/google/manifest.json 2022-04-15 07:40:52.000000000 +0000
@@ -2,7 +2,7 @@
"name": "__MSG_extensionName__",
"description": "__MSG_extensionDescription__",
"manifest_version": 2,
- "version": "1.1",
+ "version": "1.2",
"applications": {
"gecko": {
"id": "google@search.mozilla.org"
diff -Nru thunderbird-91.7.0+build2/browser/components/search/test/browser/browser_searchbar_enter.js thunderbird-91.8.1+build1/browser/components/search/test/browser/browser_searchbar_enter.js
--- thunderbird-91.7.0+build2/browser/components/search/test/browser/browser_searchbar_enter.js 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/search/test/browser/browser_searchbar_enter.js 2022-04-15 07:40:52.000000000 +0000
@@ -119,3 +119,38 @@
// Cleanup.
await BrowserTestUtils.closeWindow(win);
});
+
+add_task(async function keyupEnterWhilePressingMeta() {
+ const win = await BrowserTestUtils.openNewBrowserWindow();
+ const browser = win.gBrowser.selectedBrowser;
+ const searchBar = win.BrowserSearch.searchBar;
+
+ info("Keydown Meta+Enter");
+ searchBar.textbox.focus();
+ searchBar.textbox.value = "";
+ EventUtils.synthesizeKey(
+ "KEY_Enter",
+ { type: "keydown", metaKey: true },
+ win
+ );
+
+ // Pressing Enter key while pressing Meta key, and next, even when releasing
+ // Enter key before releasing Meta key, the keyup event is not fired.
+ // Therefor, we fire Meta keyup event only.
+ info("Keyup Meta");
+ EventUtils.synthesizeKey("KEY_Meta", { type: "keyup" }, win);
+
+ await TestUtils.waitForCondition(
+ () => browser.ownerDocument.activeElement === browser,
+ "Wait for focus to be moved to the browser"
+ );
+ info("The focus is moved to the browser");
+
+ info("Check whether we can input on the search bar");
+ searchBar.textbox.focus();
+ EventUtils.synthesizeKey("a", {}, win);
+ is(searchBar.textbox.value, "a", "Can input a char");
+
+ // Cleanup.
+ await BrowserTestUtils.closeWindow(win);
+});
diff -Nru thunderbird-91.7.0+build2/browser/components/urlbar/tests/browser/browser_enter.js thunderbird-91.8.1+build1/browser/components/urlbar/tests/browser/browser_enter.js
--- thunderbird-91.7.0+build2/browser/components/urlbar/tests/browser/browser_enter.js 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/urlbar/tests/browser/browser_enter.js 2022-04-15 07:40:52.000000000 +0000
@@ -303,3 +303,25 @@
// Cleanup.
BrowserTestUtils.removeTab(tab);
});
+
+add_task(async function keyupEnterWhilePressingMeta() {
+ const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
+
+ info("Keydown Meta+Enter");
+ gURLBar.focus();
+ gURLBar.value = "";
+ EventUtils.synthesizeKey("KEY_Enter", { type: "keydown", metaKey: true });
+
+ // Pressing Enter key while pressing Meta key, and next, even when releasing
+ // Enter key before releasing Meta key, the keyup event is not fired.
+ // Therefor, we fire Meta keyup event only.
+ info("Keyup Meta");
+ EventUtils.synthesizeKey("KEY_Meta", { type: "keyup" });
+
+ // Check whether we can input on URL bar.
+ EventUtils.synthesizeKey("a");
+ is(gURLBar.value, "a", "Can input a char");
+
+ // Cleanup.
+ BrowserTestUtils.removeTab(tab);
+});
diff -Nru thunderbird-91.7.0+build2/browser/components/urlbar/tests/unit/xpcshell.ini thunderbird-91.8.1+build1/browser/components/urlbar/tests/unit/xpcshell.ini
--- thunderbird-91.7.0+build2/browser/components/urlbar/tests/unit/xpcshell.ini 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/urlbar/tests/unit/xpcshell.ini 2022-04-15 07:40:52.000000000 +0000
@@ -71,6 +71,7 @@
[test_tokenizer.js]
[test_trimming.js]
[test_unitConversion.js]
+skip-if = true # Bug 1759318
[test_UrlbarController_integration.js]
[test_UrlbarController_telemetry.js]
[test_UrlbarController_unit.js]
diff -Nru thunderbird-91.7.0+build2/browser/components/urlbar/UrlbarInput.jsm thunderbird-91.8.1+build1/browser/components/urlbar/UrlbarInput.jsm
--- thunderbird-91.7.0+build2/browser/components/urlbar/UrlbarInput.jsm 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/components/urlbar/UrlbarInput.jsm 2022-04-15 07:40:52.000000000 +0000
@@ -3176,10 +3176,17 @@
}
async _on_keyup(event) {
- if (
- event.keyCode === KeyEvent.DOM_VK_RETURN &&
- this._keyDownEnterDeferred
- ) {
+ if (event.keyCode === KeyEvent.DOM_VK_CONTROL) {
+ this._isKeyDownWithCtrl = false;
+ }
+
+ this._toggleActionOverride(event);
+
+ // Pressing Enter key while pressing Meta key, and next, even when releasing
+ // Enter key before releasing Meta key, the keyup event is not fired.
+ // Therefore, if Enter keydown is detecting, continue the post processing
+ // for Enter key when any keyup event is detected.
+ if (this._keyDownEnterDeferred) {
if (this._keyDownEnterDeferred.loadedContent) {
try {
const loadingBrowser = await this._keyDownEnterDeferred.promise;
@@ -3189,24 +3196,19 @@
// Make sure the domain name stays visible for spoof protection and usability.
this.selectionStart = this.selectionEnd = 0;
}
- this._keyDownEnterDeferred = null;
} catch (ex) {
// Not all the Enter actions in the urlbar will cause a navigation, then it
// is normal for this to be rejected.
// If _keyDownEnterDeferred was rejected on keydown, we don't nullify it here
// to ensure not overwriting the new value created by keydown.
}
- return;
+ } else {
+ // Discard the _keyDownEnterDeferred promise to receive any key inputs immediately.
+ this._keyDownEnterDeferred.resolve();
}
- // Discard the _keyDownEnterDeferred promise to receive any key inputs immediately.
- this._keyDownEnterDeferred.resolve();
this._keyDownEnterDeferred = null;
- } else if (event.keyCode === KeyEvent.DOM_VK_CONTROL) {
- this._isKeyDownWithCtrl = false;
}
-
- this._toggleActionOverride(event);
}
_on_compositionstart(event) {
diff -Nru thunderbird-91.7.0+build2/browser/config/version_display.txt thunderbird-91.8.1+build1/browser/config/version_display.txt
--- thunderbird-91.7.0+build2/browser/config/version_display.txt 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/config/version_display.txt 2022-04-15 07:48:28.000000000 +0000
@@ -1 +1 @@
-91.7.0esr
+91.8.0esr
diff -Nru thunderbird-91.7.0+build2/browser/config/version.txt thunderbird-91.8.1+build1/browser/config/version.txt
--- thunderbird-91.7.0+build2/browser/config/version.txt 2022-03-07 21:32:51.000000000 +0000
+++ thunderbird-91.8.1+build1/browser/config/version.txt 2022-04-15 07:48:28.000000000 +0000
@@ -1 +1 @@
-91.7.0
+91.8.0
diff -Nru thunderbird-91.7.0+build2/BUILDID thunderbird-91.8.1+build1/BUILDID
--- thunderbird-91.7.0+build2/BUILDID 2022-03-07 21:42:48.000000000 +0000
+++ thunderbird-91.8.1+build1/BUILDID 2022-04-15 08:10:45.000000000 +0000
@@ -1 +1 @@
-20220305171341
\ No newline at end of file
+20220413002405
\ No newline at end of file
diff -Nru thunderbird-91.7.0+build2/Cargo.lock thunderbird-91.8.1+build1/Cargo.lock
--- thunderbird-91.7.0+build2/Cargo.lock 2022-03-07 21:32:50.000000000 +0000
+++ thunderbird-91.8.1+build1/Cargo.lock 2022-04-15 07:40:51.000000000 +0000
@@ -3888,6 +3888,7 @@
version = "0.2.0"
dependencies = [
"libc",
+ "rustc_version",
]
[[package]]
@@ -4048,9 +4049,9 @@
[[package]]
name = "regex"
-version = "1.5.4"
+version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [
"aho-corasick",
"memchr",
diff -Nru thunderbird-91.7.0+build2/comm/.gecko_rev.yml thunderbird-91.8.1+build1/comm/.gecko_rev.yml
--- thunderbird-91.7.0+build2/comm/.gecko_rev.yml 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/.gecko_rev.yml 2022-04-15 07:49:20.000000000 +0000
@@ -1,8 +1,8 @@
---
GECKO_BASE_REPOSITORY: https://hg.mozilla.org/mozilla-unified
GECKO_HEAD_REPOSITORY: https://hg.mozilla.org/releases/mozilla-esr91
-GECKO_HEAD_REF: FIREFOX_91_7_0esr_BUILD3
-GECKO_HEAD_REV: a9d3c0f4732a9a62428089fff64ae8ff3d608918
+GECKO_HEAD_REF: FIREFOX_91_8_0esr_BUILD1
+GECKO_HEAD_REV: 3b54d6b5407fca03efdb2e2f57a9838498e0d038
### For comm-central
# GECKO_BASE_REPOSITORY: https://hg.mozilla.org/mozilla-unified
diff -Nru thunderbird-91.7.0+build2/comm/ldap/modules/LDAPClient.jsm thunderbird-91.8.1+build1/comm/ldap/modules/LDAPClient.jsm
--- thunderbird-91.7.0+build2/comm/ldap/modules/LDAPClient.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/ldap/modules/LDAPClient.jsm 2022-04-15 07:49:20.000000000 +0000
@@ -9,6 +9,7 @@
var {
AbandonRequest,
BindRequest,
+ UnbindRequest,
SearchRequest,
LDAPResponse,
} = ChromeUtils.import("resource:///modules/LDAPMessage.jsm");
@@ -110,6 +111,13 @@
}
/**
+ * Send an unbind request to the server.
+ */
+ unbind() {
+ return this._send(new UnbindRequest(), () => this._socket.close());
+ }
+
+ /**
* Send a search request to the server.
* @param {string} dn - The name to search.
* @param {number} scope - The scope to search.
diff -Nru thunderbird-91.7.0+build2/comm/ldap/modules/LDAPConnection.jsm thunderbird-91.8.1+build1/comm/ldap/modules/LDAPConnection.jsm
--- thunderbird-91.7.0+build2/comm/ldap/modules/LDAPConnection.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/ldap/modules/LDAPConnection.jsm 2022-04-15 07:49:20.000000000 +0000
@@ -41,6 +41,11 @@
this.client.connect();
}
+ close() {
+ this.client.onError = () => {};
+ this.client.unbind();
+ }
+
get wrappedJSObject() {
return this;
}
diff -Nru thunderbird-91.7.0+build2/comm/ldap/modules/LDAPMessage.jsm thunderbird-91.8.1+build1/comm/ldap/modules/LDAPMessage.jsm
--- thunderbird-91.7.0+build2/comm/ldap/modules/LDAPMessage.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/ldap/modules/LDAPMessage.jsm 2022-04-15 07:49:20.000000000 +0000
@@ -5,6 +5,7 @@
const EXPORTED_SYMBOLS = [
"AbandonRequest",
"BindRequest",
+ "UnbindRequest",
"SearchRequest",
"LDAPResponse",
];
@@ -124,6 +125,15 @@
}
}
+class UnbindRequest extends LDAPMessage {
+ static APPLICATION = 2;
+
+ protocolOp = new asn1js.Primitive({
+ // [APPLICATION 2]
+ idBlock: this._getApplicationId(UnbindRequest.APPLICATION),
+ });
+}
+
class SearchRequest extends LDAPMessage {
static APPLICATION = 3;
diff -Nru thunderbird-91.7.0+build2/comm/ldap/modules/LDAPOperation.jsm thunderbird-91.8.1+build1/comm/ldap/modules/LDAPOperation.jsm
--- thunderbird-91.7.0+build2/comm/ldap/modules/LDAPOperation.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/ldap/modules/LDAPOperation.jsm 2022-04-15 07:49:20.000000000 +0000
@@ -92,6 +92,9 @@
},
});
} else if (res.constructor.name == "SearchResultDone") {
+ // NOTE: we create a new connection for every search, can be changed
+ // to reuse connections.
+ this._connection.wrappedJSObject.close();
this._messageId = null;
this._listener.onLDAPMessage({
errorCode: res.result.resultCode,
diff -Nru thunderbird-91.7.0+build2/comm/mail/app/settings/dumps/thunderbird/search-config.json thunderbird-91.8.1+build1/comm/mail/app/settings/dumps/thunderbird/search-config.json
--- thunderbird-91.7.0+build2/comm/mail/app/settings/dumps/thunderbird/search-config.json 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/app/settings/dumps/thunderbird/search-config.json 2022-04-15 07:49:21.000000000 +0000
@@ -1 +1,2481 @@
-{"data":[{"appliesTo":[{"included":{"everywhere":true}}],"orderHint":500,"telemetryId":"ddg","webExtension":{"id":"ddg@search.mozilla.org","version":"1.0"},"id":"2c33bcaa-aae3-42e5-ad0d-915e2e822cc9","last_modified":1604535069307},{"appliesTo":[{"included":{"everywhere":true}},{"included":{"locales":{"matches":["af","an","ar","as","ast","az","be","bg","br","bs","crh","cy","da","de","dsb","el","eo","et","eu","fa","fi","fy-NL","ga-IE","gd","gl","gn","he","hr","hsb","hu","ia","id","is","it","ka","kab","kk","km","kn","lij","lo","lt","ltg","lv","mk","ml","mr","ms","my","nl","oc","or","pl","rm","ro","ru","si","sk","sl","sq","sr","sv-SE","ta","te","th","tl","tr","uk","ur","uz","vi","wo","zh-CN","zh-TW"]}},"webExtension":{"locales":["$USER_LOCALE"]}},{"included":{"locales":{"matches":["be"]}},"webExtension":{"locales":["be","be-tarask"]}},{"included":{"locales":{"matches":["bn","bn-BD","bn-IN"]}},"webExtension":{"locales":["bn"]}},{"included":{"locales":{"matches":["ca","ca-valencia"]}},"webExtension":{"locales":["ca"]}},{"included":{"locales":{"matches":["cak","es-AR","es-CL","es-ES","es-MX","trs"]}},"webExtension":{"locales":["es"]}},{"included":{"locales":{"matches":["cs"]}},"webExtension":{"locales":["cz"]}},{"included":{"locales":{"matches":["ff","fr","son"]}},"webExtension":{"locales":["fr"]}},{"included":{"locales":{"matches":["gu-IN"]}},"webExtension":{"locales":["gu"]}},{"included":{"locales":{"matches":["hi-IN"]}},"webExtension":{"locales":["hi"]}},{"included":{"locales":{"matches":["hy-AM"]}},"webExtension":{"locales":["hy"]}},{"included":{"locales":{"matches":["ja-JP-macos","ja"]}},"webExtension":{"locales":["ja"]}},{"included":{"locales":{"matches":["ko"]}},"webExtension":{"locales":["kr"]}},{"included":{"locales":{"matches":["mai"]}},"webExtension":{"locales":["hi"]}},{"included":{"locales":{"matches":["ml"]}},"webExtension":{"locales":["en","ml"]}},{"included":{"locales":{"matches":["nb-NO"]}},"webExtension":{"locales":["NO"]}},{"included":{"locales":{"matches":["ne-NP"]}},"webExtension":{"locales":["ne"]}},{"included":{"locales":{"matches":["nn-NO"]}},"webExtension":{"locales":["NN"]}},{"included":{"locales":{"matches":["pa-IN"]}},"webExtension":{"locales":["pa"]}},{"included":{"locales":{"matches":["pt-BR","pt-PT"]}},"webExtension":{"locales":["pt"]}}],"webExtension":{"id":"wikipedia@search.mozilla.org","version":"1.0"},"id":"8563efb6-e9f5-4f83-88b4-5124e5a51885","last_modified":1597452131957},{"appliesTo":[{"included":{"locales":{"matches":["sk"]}}}],"webExtension":{"id":"zoznam-sk@search.mozilla.org","version":"1.2"},"id":"208e5b83-ea31-4ad3-b5b1-8c46fdb646d2","last_modified":1597452131934},{"appliesTo":[{"included":{"locales":{"matches":["ja-JP-macos","ja"]}}}],"webExtension":{"id":"yahoo-jp-auctions@search.mozilla.org","version":"1.2"},"id":"3d048cc7-0b49-49f1-8275-25562f997cd4","last_modified":1597452131911},{"appliesTo":[{"included":{"locales":{"matches":["ja-JP-macos","ja"]}}}],"webExtension":{"id":"yahoo-jp@search.mozilla.org","version":"1.0"},"id":"4a3c25e9-32fc-43ba-9f64-04f44f23edf0","last_modified":1597452131889},{"appliesTo":[{"included":{"locales":{"matches":["pl"]}}}],"webExtension":{"id":"wolnelektury-pl@search.mozilla.org","version":"1.0"},"id":"cebf41a8-bb48-4f5a-b05a-404e57c4e019","last_modified":1597452131866},{"appliesTo":[{"included":{"locales":{"matches":["te"]}},"webExtension":{"locales":["te"]}},{"included":{"locales":{"matches":["oc"]}},"webExtension":{"locales":["oc"]}}],"webExtension":{"id":"wiktionary@search.mozilla.org","version":"1.0"},"id":"676fad59-3280-4e5d-a3ae-74c918f6b8d3","last_modified":1597452131842},{"appliesTo":[{"included":{"locales":{"matches":["hu"]}}}],"webExtension":{"id":"vatera@search.mozilla.org","version":"1.2"},"id":"ff997f3f-e41c-44e2-96b2-419a1ed7e7c4","last_modified":1597452131820},{"appliesTo":[{"included":{"locales":{"matches":["sv-SE"]}}}],"webExtension":{"id":"tyda-sv-SE@search.mozilla.org","version":"1.0"},"id":"f3930927-4422-4cc1-9576-b70a80e528b8","last_modified":1597452131797},{"appliesTo":[{"included":{"locales":{"matches":["ga-IE"]}}}],"webExtension":{"id":"tearma@search.mozilla.org","version":"1.0"},"id":"ada324f8-3081-4397-b78b-e03bd860375e","last_modified":1597452131747},{"appliesTo":[{"included":{"locales":{"matches":["ltg","lv"]}}}],"webExtension":{"id":"sslv@search.mozilla.org","version":"1.0"},"id":"3f907fb8-c074-444a-850f-b6ea3a651c56","last_modified":1597452131724},{"appliesTo":[{"included":{"locales":{"matches":["cs"]}}}],"webExtension":{"id":"seznam-cz@search.mozilla.org","version":"1.0"},"id":"38f61654-35a4-4c93-af84-7c215edaf434","last_modified":1597452131701},{"appliesTo":[{"included":{"locales":{"matches":["ltg","lv"]}}}],"webExtension":{"id":"salidzinilv@search.mozilla.org","version":"1.0"},"id":"6bec5c4a-0f12-4399-b4d5-2fe9d73c0e74","last_modified":1597452131679},{"appliesTo":[{"included":{"locales":{"matches":["zh-TW"]}}}],"webExtension":{"id":"readmoo@search.mozilla.org","version":"1.0"},"id":"4399d0ea-7540-43f6-adbd-4833b341ba9f","last_modified":1597452131655},{"appliesTo":[{"included":{"locales":{"matches":["ja-JP-macos","jp"]}}}],"webExtension":{"id":"rakuten@search.mozilla.org","version":"1.2"},"id":"fc2c153a-936c-4d7e-a72c-e0a7ce23b6d8","last_modified":1597452131632},{"appliesTo":[{"included":{"locales":{"matches":["nb-NO","nn-NO"]}}}],"webExtension":{"id":"qxl-NO@search.mozilla.org","version":"1.0"},"id":"dfc109bd-b4e5-4aa9-95a3-5cd81d67341d","last_modified":1597452131611},{"appliesTo":[{"included":{"locales":{"matches":["fr"]}}}],"webExtension":{"id":"qwant@search.mozilla.org","version":"1.0"},"id":"a0ce2b21-9204-486d-b0a1-07819e38b2e0","last_modified":1597452131588},{"appliesTo":[{"included":{"locales":{"matches":["pl"]}}}],"webExtension":{"id":"pwn-pl@search.mozilla.org","version":"1.0"},"id":"3f0b73cf-2645-427a-acbd-f9b9a7e86ca9","last_modified":1597452131564},{"appliesTo":[{"included":{"locales":{"matches":["sv-SE"]}}}],"webExtension":{"id":"prisjakt-sv-SE@search.mozilla.org","version":"1.0"},"id":"1a571c53-a05e-483f-ba76-944ce03e405c","last_modified":1597452131543},{"appliesTo":[{"included":{"locales":{"matches":["ru"]}}}],"webExtension":{"id":"priceru@search.mozilla.org","version":"1.0"},"id":"2ca250af-f2ac-4f63-af34-1b1b53fd3b92","last_modified":1597452131520},{"appliesTo":[{"included":{"locales":{"matches":["pt-PT"]}}}],"webExtension":{"id":"priberam@search.mozilla.org","version":"1.2"},"id":"44c5c666-422b-4fc2-b9e2-cddd0d3b7ccc","last_modified":1597452131497},{"appliesTo":[{"included":{"locales":{"matches":["sr"]}}}],"webExtension":{"id":"pogodak@search.mozilla.org","version":"1.0"},"id":"473fd16b-ed84-4ed1-822c-50ac5d9ee63b","last_modified":1597452131475},{"appliesTo":[{"included":{"locales":{"matches":["bg"]}}}],"webExtension":{"id":"pazaruvaj@search.mozilla.org","version":"1.0"},"id":"6752ecbe-99cc-4ce9-90db-31c8d9e7c506","last_modified":1597452131452},{"appliesTo":[{"included":{"locales":{"matches":["cy"]}}}],"webExtension":{"id":"palasprint@search.mozilla.org","version":"1.0"},"id":"1f5075fa-ed75-4561-919f-3fa6e1158bf7","last_modified":1597452131429},{"appliesTo":[{"included":{"locales":{"matches":["ru"]}}}],"webExtension":{"id":"ozonru@search.mozilla.org","version":"1.2"},"id":"954cc2fe-72f5-4360-b200-ab455c5ad920","last_modified":1597452131407},{"appliesTo":[{"included":{"locales":{"matches":["et"]}}}],"webExtension":{"id":"osta-ee@search.mozilla.org","version":"1.0"},"id":"e4e7b227-f6e6-49bf-840a-a7b7601e1a92","last_modified":1597452131384},{"appliesTo":[{"included":{"locales":{"matches":["ja-JP-macos","jp"]}}}],"webExtension":{"id":"oshiete-goo@search.mozilla.org","version":"1.0"},"id":"ba06b66e-b083-42f9-96ca-06beb7df003b","last_modified":1597452131360},{"appliesTo":[{"included":{"locales":{"matches":["bs"]}}}],"webExtension":{"id":"olx@search.mozilla.org","version":"1.0"},"id":"0a2b2d3b-18d7-425d-b852-319cafe49d22","last_modified":1597452131338},{"appliesTo":[{"included":{"locales":{"matches":["sl"]}}}],"webExtension":{"id":"odpiralni@search.mozilla.org","version":"1.0"},"id":"7e85688f-5f3e-4dce-a624-6a80ea792a39","last_modified":1597452131315},{"appliesTo":[{"included":{"locales":{"matches":["et"]}}}],"webExtension":{"id":"neti-ee@search.mozilla.org","version":"1.0"},"id":"c7cd702e-9049-4a75-823c-6ccd7ad2b86f","last_modified":1597452131292},{"appliesTo":[{"included":{"locales":{"matches":["ko"]}}}],"webExtension":{"id":"naver-kr@search.mozilla.org","version":"1.0"},"id":"af1943a3-75e1-4429-8a95-43675686786c","last_modified":1597452131271},{"appliesTo":[{"included":{"locales":{"matches":["sl"]}}}],"webExtension":{"id":"najdi-si@search.mozilla.org","version":"1.0"},"id":"fda60f56-ac34-410a-8e74-1b2ba0dbaeaa","last_modified":1597452131248},{"appliesTo":[{"included":{"locales":{"matches":["he"]}}}],"webExtension":{"id":"morfix-dic@search.mozilla.org","version":"1.1"},"id":"2950bf4a-450f-47cd-8988-1d9d73c10300","last_modified":1597452131225},{"appliesTo":[{"included":{"locales":{"matches":["pt-BR"]}}}],"webExtension":{"id":"mercadolivre@search.mozilla.org","version":"1.0"},"id":"393eed85-f54c-453c-9df3-d5351473a2d0","last_modified":1597452131204},{"appliesTo":[{"included":{"locales":{"matches":["es-AR"]}},"webExtension":{"locales":["ar"]}},{"included":{"locales":{"matches":["es-CL"]}},"webExtension":{"locales":["cl"]}},{"included":{"locales":{"matches":["es-MX"]}},"webExtension":{"locales":["mx"]}}],"webExtension":{"id":"mercadolibre@search.mozilla.org","version":"1.0"},"id":"58ccc938-9b28-43fa-99c8-8fb2afaf0531","last_modified":1597452131181},{"appliesTo":[{"included":{"locales":{"matches":["fy-NL"]}},"webExtension":{"locales":["fy-NL"]}},{"included":{"locales":{"matches":["nl"]}},"webExtension":{"locales":["nl"]}}],"webExtension":{"id":"marktplaats@search.mozilla.org","version":"1.0"},"id":"5e341152-6dc1-4357-80cb-8c2d615ec5dc","last_modified":1597452131158},{"appliesTo":[{"included":{"locales":{"matches":["cs"]}}}],"webExtension":{"id":"mapy-cz@search.mozilla.org","version":"1.0"},"id":"bcee8873-4644-44c1-babf-b35be366f4f7","last_modified":1597452131136},{"appliesTo":[{"included":{"locales":{"matches":["ru"]}}}],"webExtension":{"id":"mailru@search.mozilla.org","version":"1.0"},"id":"969a8778-1f6d-4af2-87cd-c08a9a4f80b8","last_modified":1597452131114},{"appliesTo":[{"included":{"locales":{"matches":["th"]}}}],"webExtension":{"id":"longdo@search.mozilla.org","version":"1.0"},"id":"c64fefb6-61b5-49fe-8148-1470fa586c21","last_modified":1597452131091},{"appliesTo":[{"included":{"locales":{"matches":["hy-AM"]}}}],"webExtension":{"id":"list-am@search.mozilla.org","version":"1.0"},"id":"2e099aaa-b949-4038-8595-69678b09c46d","last_modified":1597452131070},{"appliesTo":[{"included":{"locales":{"matches":["de","dsb","hsb","rm"]}}}],"webExtension":{"id":"leo_ende_de@search.mozilla.org","version":"1.0"},"id":"4db2ab80-c651-405b-88ba-1b30396a5d23","last_modified":1597452131047},{"appliesTo":[{"included":{"locales":{"matches":["kn"]}}}],"webExtension":{"id":"kannadastore@search.mozilla.org","version":"1.2"},"id":"8cb31936-c2da-47b6-8acc-15e2d48d2362","last_modified":1597452131024},{"appliesTo":[{"included":{"locales":{"matches":["uk"]}}}],"webExtension":{"id":"hotline-ua@search.mozilla.org","version":"1.0"},"id":"5b2895b4-afb4-452d-bc8f-4b3752448fba","last_modified":1597452131003},{"appliesTo":[{"included":{"locales":{"matches":["cs"]}}}],"webExtension":{"id":"heureka-cz@search.mozilla.org","version":"1.0"},"id":"dfc28b2a-40ac-4772-bca3-8b090ab8a05e","last_modified":1597452130980},{"appliesTo":[{"included":{"locales":{"matches":["nn-NO","nb-NO"]}}}],"webExtension":{"id":"gulesider-NO@search.mozilla.org","version":"1.0"},"id":"311b0b99-0619-446f-ad7c-695e531ec000","last_modified":1597452130957},{"appliesTo":[{"included":{"locales":{"matches":["br"]}}}],"webExtension":{"id":"freelang@search.mozilla.org","version":"1.0"},"id":"e72ce961-ea88-4296-ac41-745d75c14363","last_modified":1597452130936},{"appliesTo":[{"included":{"locales":{"matches":["kk"]}}}],"webExtension":{"id":"flip@search.mozilla.org","version":"1.0"},"id":"0b17f642-5519-4e5b-89bb-71e16e3e0763","last_modified":1597452130913},{"appliesTo":[{"included":{"locales":{"matches":["gd"]}}}],"webExtension":{"id":"faclair-beag@search.mozilla.org","version":"1.0"},"id":"2b046c0d-3cc6-4639-8454-2d2ea024705b","last_modified":1597452130891},{"appliesTo":[{"included":{"locales":{"matches":["hr"]}}}],"webExtension":{"id":"eudict@search.mozilla.org","version":"1.0"},"id":"1bf9f430-9b92-4c3b-a2c1-0a7edddc1f28","last_modified":1597452130869},{"appliesTo":[{"included":{"locales":{"matches":["et"]}}}],"webExtension":{"id":"eki-ee@search.mozilla.org","version":"1.0"},"id":"7c60a125-37c2-48f1-b541-86fe070b4388","last_modified":1597452130847},{"appliesTo":[{"included":{"locales":{"matches":["de"]}}}],"webExtension":{"id":"ecosia@search.mozilla.org","version":"1.0"},"id":"e7083870-11cf-4c2b-8843-67b3e098f474","last_modified":1597452130824},{"appliesTo":[{"included":{"locales":{"matches":["es-AR","es-CL","es-ES"]}}}],"webExtension":{"id":"drae@search.mozilla.org","version":"1.0"},"id":"fcf39b52-b59d-42a5-b1a8-4361159b428d","last_modified":1597452130803},{"appliesTo":[{"included":{"locales":{"matches":["ca","ca-valencia"]}}}],"webExtension":{"id":"diec2@search.mozilla.org","version":"1.2"},"id":"b88830cd-705d-492a-a28c-742abfa9334b","last_modified":1597452130780},{"appliesTo":[{"included":{"locales":{"matches":["ko"]}}}],"webExtension":{"id":"daum-kr@search.mozilla.org","version":"1.0"},"id":"2dc000ee-a78b-4e78-91af-ac76b79bac47","last_modified":1597452130756},{"appliesTo":[{"included":{"locales":{"matches":["vi"]}}}],"webExtension":{"id":"coccoc@search.mozilla.org","version":"1.0"},"id":"cd8d215b-6c81-439b-bc16-dab6bae8188b","last_modified":1597452130735},{"appliesTo":[{"included":{"locales":{"matches":["en-GB"]}}}],"webExtension":{"id":"chambers-en-GB@search.mozilla.org","version":"1.0"},"id":"7047c29e-7ad4-49db-adb9-6c135e6c59f8","last_modified":1597452130712},{"appliesTo":[{"included":{"locales":{"matches":["sl"]}}}],"webExtension":{"id":"ceneji@search.mozilla.org","version":"1.0"},"id":"c0fe16a1-6d66-48a2-bc54-ceb9a78754ce","last_modified":1597452130688},{"appliesTo":[{"included":{"locales":{"matches":["fy-NL"]}},"webExtension":{"locales":["fy-NL"]}},{"included":{"locales":{"matches":["nl"]}},"webExtension":{"locales":["nl"]}}],"webExtension":{"id":"bolcom@search.mozilla.org","version":"1.0"},"id":"adc06075-02c9-4d8d-88ab-bccd1b843184","last_modified":1597452130667},{"appliesTo":[{"included":{"locales":{"matches":["nb-NO","nn-NO"]}}}],"webExtension":{"id":"bok-NO@search.mozilla.org","version":"1.0"},"id":"dc33bc2b-758b-41fe-804c-e9894aea9cc1","last_modified":1597452130644},{"appliesTo":[{"included":{"locales":{"matches":["gd"]}}}],"webExtension":{"id":"bbc-alba@search.mozilla.org","version":"1.0"},"id":"614c27ea-1537-4db0-ac1d-b873732bde57","last_modified":1597452130621},{"appliesTo":[{"included":{"locales":{"matches":["sk"]}}}],"webExtension":{"id":"azet-sk@search.mozilla.org","version":"1.0"},"id":"17835df2-e2b8-4ca8-91bc-a45299bdcae5","last_modified":1597452130600},{"appliesTo":[{"included":{"locales":{"matches":["az"]}}}],"webExtension":{"id":"azerdict@search.mozilla.org","version":"1.0"},"id":"85d4f0c7-ace1-4e67-9e16-38db2aebf84b","last_modified":1597452130577},{"appliesTo":[{"included":{"locales":{"matches":["sk"]}}}],"webExtension":{"id":"atlas-sk@search.mozilla.org","version":"1.0"},"id":"bb87e317-4ba3-458e-9b64-d4459e61b001","last_modified":1597452130554},{"appliesTo":[{"included":{"locales":{"matches":["pl"]}}}],"webExtension":{"id":"allegro-pl@search.mozilla.org","version":"1.0"},"id":"9933195c-160e-41bb-984b-019137687d48","last_modified":1597452130533},{"appliesTo":[{"included":{"locales":{"matches":["sv-SE"]}}}],"webExtension":{"id":"allaannonser-sv-SE@search.mozilla.org","version":"1.2"},"id":"7011ae79-112a-494a-834b-857b66e444c0","last_modified":1597452130511},{"appliesTo":[{"default":"yes","included":{"locales":{"matches":["ru","tr","be","kk"],"startsWith":["en"]},"regions":["ru","tr","by","kz"]},"telemetryId":"yandex-en","webExtension":{"locales":["en"]}},{"included":{"locales":{"matches":["az"]}},"telemetryId":"yandex-az","webExtension":{"locales":["az"]}},{"included":{"locales":{"matches":["be"]}},"telemetryId":"yandex-by","webExtension":{"locales":["by"]}},{"included":{"locales":{"matches":["kk"]}},"telemetryId":"yandex-kk","webExtension":{"locales":["kk"]}},{"included":{"locales":{"matches":["ru"]}},"telemetryId":"yandex-ru","webExtension":{"locales":["ru"]}},{"included":{"locales":{"matches":["tr"]}},"telemetryId":"yandex-tr","webExtension":{"locales":["tr"]}}],"webExtension":{"id":"yandex@search.mozilla.org","version":"1.0"},"id":"cdfef3b9-59a5-4e58-998b-8f61e5f63279","last_modified":1597452130488},{"params":{"searchUrlGetParams":{"ix":"sunray","Go.x":"0","Go.y":"0","keywords":"{searchTerms}","pageletid":"headsearch","searchType":"","bestSaleNum":"0"}},"appliesTo":[{"included":{"locales":{"matches":["zh-CN"]}}}],"orderHint":500,"telemetryId":"amazondotcn","webExtension":{"id":"amazondotcn@search.mozilla.org","version":"1.0"},"id":"965270fc-b4ee-4dcc-bdcb-fed87fe563a9","last_modified":1597452130444},{"params":{"searchUrlGetParams":[{"name":"field-keywords","value":"{searchTerms}"},{"name":"ie","value":"{inputEncoding}"},{"name":"mode","value":"blended"}]},"appliesTo":[{"included":{"locales":{"matches":["as","bn","bn-IN","kn","gu-IN","mai","ml","mr","or","pa-IN","ta","te","ur"]}},"telemetryId":"amazon-in","webExtension":{"locales":["in"]}},{"params":{"searchUrlGetParams":[{"name":"field-keywords","value":"{searchTerms}"},{"name":"ie","value":"{inputEncoding}"},{"name":"mode","value":"blended"},{"name":"sourceid","value":"Mozilla-search"}]},"included":{"locales":{"matches":["br","ff","fr","son","wo"]}},"telemetryId":"amazon-france","webExtension":{"locales":["france"]}},{"included":{"locales":{"matches":["br","ff","fr","son","wo"]},"regions":["ca"]},"telemetryId":"amazon-ca","webExtension":{"locales":["ca"]}},{"included":{"locales":{"matches":["en-CA"]}},"telemetryId":"amazon-ca","webExtension":{"locales":["ca"]}},{"params":{"searchUrlGetParams":[{"name":"field-keywords","value":"{searchTerms}"},{"name":"ie","value":"{inputEncoding}"},{"name":"mode","value":"blended"},{"name":"sourceid","value":"Mozilla-search"}]},"included":{"locales":{"matches":["ja-JP-macos","ja"]}},"telemetryId":"amazon-jp","webExtension":{"locales":["jp"]}},{"params":{"searchUrlGetParams":[{"name":"field-keywords","value":"{searchTerms}"},{"name":"ie","value":"{inputEncoding}"},{"name":"mode","value":"blended"},{"name":"sourceid","value":"Mozilla-search"}]},"included":{"locales":{"matches":["it","lij"]}},"telemetryId":"amazon-it","webExtension":{"locales":["it"]}},{"params":{"searchUrlGetParams":[{"name":"field-keywords","value":"{searchTerms}"},{"name":"ie","value":"{inputEncoding}"},{"name":"mode","value":"blended"},{"name":"sourceid","value":"Mozilla-search"}]},"included":{"locales":{"matches":["de","dsb","hsb"]}},"telemetryId":"amazon-de","webExtension":{"locales":["de"]}},{"params":{"searchUrlGetParams":[{"name":"field-keywords","value":"{searchTerms}"},{"name":"ie","value":"{inputEncoding}"},{"name":"mode","value":"blended"},{"name":"sourceid","value":"Mozilla-search"}]},"included":{"locales":{"matches":["cy","da","el","en-GB","eu","ga-IE","gd","gl","hr","nb-NO","nn-NO","pt-PT","sq","sr"]}},"telemetryId":"amazon-en-GB","webExtension":{"locales":["en-GB"]}},{"included":{"locales":{"matches":["cy","da","el","en-GB","eu","ga-IE","gd","gl","hr","nb-NO","nn-NO","pt-PT","sq","sr"]},"regions":["au"]},"telemetryId":"amazon-au","webExtension":{"locales":["au"]}}],"orderHint":500,"webExtension":{"id":"amazon@search.mozilla.org","version":"1.1"},"id":"968c66a0-0d32-4bdb-a132-66d0e7dead54","last_modified":1597452130421},{"params":{"searchUrlGetParams":[{"name":"field-keywords","value":"{searchTerms}"},{"name":"ie","value":"{inputEncoding}"},{"name":"mode","value":"blended"},{"name":"sourceid","value":"Mozilla-search"}]},"appliesTo":[{"included":{"regions":["default"]}},{"included":{"locales":{"matches":["ach","af","ar","az","bg","cak","en-US","eo","es-AR","fa","gn","hy-AM","ia","is","ka","km","lt","mk","ms","my","ro","si","th","tl","trs","uz"]}}},{"included":{"locales":{"matches":["ach","af","ar","az","bg","cak","en-US","eo","es-AR","fa","gn","hy-AM","ia","is","ka","km","lt","mk","ms","my","ro","si","th","tl","trs","uz"]},"regions":["au"]},"telemetryId":"amazon-au","webExtension":{"id":"amazon@search.mozilla.org","locales":["au"],"version":"1.1"}},{"included":{"locales":{"matches":["ach","af","ar","az","bg","cak","en-US","eo","es-AR","fa","gn","hy-AM","ia","is","ka","km","lt","mk","ms","my","ro","si","th","tl","trs","uz"]},"regions":["ca"]},"telemetryId":"amazon-ca","webExtension":{"id":"amazon@search.mozilla.org","locales":["ca"],"version":"1.1"}},{"params":{"searchUrlGetParams":[{"name":"field-keywords","value":"{searchTerms}"},{"name":"ie","value":"{inputEncoding}"},{"name":"mode","value":"blended"},{"name":"sourceid","value":"Mozilla-search"}]},"included":{"locales":{"matches":["ach","af","ar","az","bg","cak","en-US","eo","es-AR","fa","gn","hy-AM","ia","is","ka","km","lt","mk","ms","my","ro","si","th","tl","trs","uz"]},"regions":["fr"]},"telemetryId":"amazon-france","webExtension":{"id":"amazon@search.mozilla.org","locales":["france"],"version":"1.1"}},{"params":{"searchUrlGetParams":[{"name":"field-keywords","value":"{searchTerms}"},{"name":"ie","value":"{inputEncoding}"},{"name":"mode","value":"blended"},{"name":"sourceid","value":"Mozilla-search"}]},"included":{"locales":{"matches":["ach","af","ar","az","bg","cak","en-US","eo","es-AR","fa","gn","hy-AM","ia","is","ka","km","lt","mk","ms","my","ro","si","th","tl","trs","uz"]},"regions":["gb"]},"telemetryId":"amazon-en-GB","webExtension":{"id":"amazon@search.mozilla.org","locales":["en-GB"],"version":"1.1"}}],"orderHint":500,"telemetryId":"amazondotcom","webExtension":{"id":"amazondotcom@search.mozilla.org","version":"1.1"},"id":"5eb7e179-c11d-4029-99b7-bc7ea1467d46","last_modified":1597452130399},{"params":{"searchUrlGetParams":[{"name":"wd","value":"{searchTerms}"},{"name":"tn","value":"monline_7_dg"},{"name":"ie","value":"utf-8"}],"suggestUrlGetParams":[{"name":"wd","value":"{searchTerms}"},{"name":"tn","value":"monline_7_dg"},{"name":"ie","value":"utf-8"},{"name":"action","value":"opensearch"}]},"appliesTo":[{"included":{"locales":{"matches":["zh-CN"]}}},{"default":"yes","included":{"locales":{"matches":["zh-CN"]},"regions":["cn"]}}],"telemetryId":"baidu","webExtension":{"id":"baidu@search.mozilla.org","version":"1.0"},"id":"59f371ee-05cc-4c9e-8961-27fe1fa4cbc2","last_modified":1597452130376},{"params":{"searchUrlGetParams":[{"name":"q","value":"{searchTerms}"}]},"appliesTo":[{"included":{"locales":{"matches":["ach","af","an","ar","ast","az","ca","ca-valencia","cak","da","de","dsb","el","eo","es-CL","es-ES","es-MX","eu","fa","ff","fi","fr","fy-NL","gn","gu-IN","hi-IN","hr","hsb","ia","is","it","ja-JP-macos","ja","ka","kab","km","kn","lij","lo","lt","mai","mk","ml","ms","my","nb-NO","ne-NP","nl","nn-NO","oc","or","pa-IN","pt-BR","rm","ro","son","sq","sr","sv-SE","th","tl","trs","uk","ur","uz","wo","xh","zh-CN"],"startsWith":["bn","en"]}}},{"included":{"regions":["default"]}}],"webExtension":{"id":"bing@search.mozilla.org","version":"1.0"},"id":"d6b19d48-c263-49f9-9f5b-72fb5a3824bc","last_modified":1597452130353},{"params":{"searchUrlGetParams":[{"name":"q","value":"{searchTerms}"}]},"appliesTo":[{"default":"yes-if-no-other","included":{"everywhere":true}}],"orderHint":1000,"telemetryId":"google","webExtension":{"id":"google@search.mozilla.org","version":"1.0"},"id":"6158e467-c0d3-48e8-a5cf-a2102b7f9456","last_modified":1597452130330}]}
\ No newline at end of file
+{
+ "data": [
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "everywhere": true
+ }
+ }
+ ],
+ "orderHint": 500,
+ "telemetryId": "ddg",
+ "webExtension": {
+ "id": "ddg@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "2c33bcaa-aae3-42e5-ad0d-915e2e822cc9",
+ "last_modified": 1604535069307
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "everywhere": true
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "af",
+ "an",
+ "ar",
+ "as",
+ "ast",
+ "az",
+ "be",
+ "bg",
+ "br",
+ "bs",
+ "crh",
+ "cy",
+ "da",
+ "de",
+ "dsb",
+ "el",
+ "eo",
+ "et",
+ "eu",
+ "fa",
+ "fi",
+ "fy-NL",
+ "ga-IE",
+ "gd",
+ "gl",
+ "gn",
+ "he",
+ "hr",
+ "hsb",
+ "hu",
+ "ia",
+ "id",
+ "is",
+ "it",
+ "ka",
+ "kab",
+ "kk",
+ "km",
+ "kn",
+ "lij",
+ "lo",
+ "lt",
+ "ltg",
+ "lv",
+ "mk",
+ "ml",
+ "mr",
+ "ms",
+ "my",
+ "nl",
+ "oc",
+ "or",
+ "pl",
+ "rm",
+ "ro",
+ "ru",
+ "si",
+ "sk",
+ "sl",
+ "sq",
+ "sr",
+ "sv-SE",
+ "ta",
+ "te",
+ "th",
+ "tl",
+ "tr",
+ "uk",
+ "ur",
+ "uz",
+ "vi",
+ "wo",
+ "zh-CN",
+ "zh-TW"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "$USER_LOCALE"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "be"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "be",
+ "be-tarask"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "bn",
+ "bn-BD",
+ "bn-IN"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "bn"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ca",
+ "ca-valencia"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "ca"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "cak",
+ "es-AR",
+ "es-CL",
+ "es-ES",
+ "es-MX",
+ "trs"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "es"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "cs"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "cz"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ff",
+ "fr",
+ "son"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "fr"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "gu-IN"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "gu"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "hi-IN"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "hi"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "hy-AM"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "hy"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ja-JP-macos",
+ "ja"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "ja"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ko"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "kr"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "mai"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "hi"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ml"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "en",
+ "ml"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "nb-NO"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "NO"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ne-NP"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "ne"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "nn-NO"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "NN"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "pa-IN"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "pa"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "pt-BR",
+ "pt-PT"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "pt"
+ ]
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "wikipedia@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "8563efb6-e9f5-4f83-88b4-5124e5a51885",
+ "last_modified": 1597452131957
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sk"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "zoznam-sk@search.mozilla.org",
+ "version": "1.2"
+ },
+ "id": "208e5b83-ea31-4ad3-b5b1-8c46fdb646d2",
+ "last_modified": 1597452131934
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ja-JP-macos",
+ "ja"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "yahoo-jp-auctions@search.mozilla.org",
+ "version": "1.2"
+ },
+ "id": "3d048cc7-0b49-49f1-8275-25562f997cd4",
+ "last_modified": 1597452131911
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ja-JP-macos",
+ "ja"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "yahoo-jp@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "4a3c25e9-32fc-43ba-9f64-04f44f23edf0",
+ "last_modified": 1597452131889
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "pl"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "wolnelektury-pl@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "cebf41a8-bb48-4f5a-b05a-404e57c4e019",
+ "last_modified": 1597452131866
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "te"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "te"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "oc"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "oc"
+ ]
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "wiktionary@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "676fad59-3280-4e5d-a3ae-74c918f6b8d3",
+ "last_modified": 1597452131842
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "hu"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "vatera@search.mozilla.org",
+ "version": "1.2"
+ },
+ "id": "ff997f3f-e41c-44e2-96b2-419a1ed7e7c4",
+ "last_modified": 1597452131820
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sv-SE"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "tyda-sv-SE@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "f3930927-4422-4cc1-9576-b70a80e528b8",
+ "last_modified": 1597452131797
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ga-IE"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "tearma@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "ada324f8-3081-4397-b78b-e03bd860375e",
+ "last_modified": 1597452131747
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ltg",
+ "lv"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "sslv@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "3f907fb8-c074-444a-850f-b6ea3a651c56",
+ "last_modified": 1597452131724
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "cs"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "seznam-cz@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "38f61654-35a4-4c93-af84-7c215edaf434",
+ "last_modified": 1597452131701
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ltg",
+ "lv"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "salidzinilv@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "6bec5c4a-0f12-4399-b4d5-2fe9d73c0e74",
+ "last_modified": 1597452131679
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "zh-TW"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "readmoo@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "4399d0ea-7540-43f6-adbd-4833b341ba9f",
+ "last_modified": 1597452131655
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ja-JP-macos",
+ "jp"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "rakuten@search.mozilla.org",
+ "version": "1.2"
+ },
+ "id": "fc2c153a-936c-4d7e-a72c-e0a7ce23b6d8",
+ "last_modified": 1597452131632
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "nb-NO",
+ "nn-NO"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "qxl-NO@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "dfc109bd-b4e5-4aa9-95a3-5cd81d67341d",
+ "last_modified": 1597452131611
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "fr"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "qwant@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "a0ce2b21-9204-486d-b0a1-07819e38b2e0",
+ "last_modified": 1597452131588
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "pl"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "pwn-pl@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "3f0b73cf-2645-427a-acbd-f9b9a7e86ca9",
+ "last_modified": 1597452131564
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sv-SE"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "prisjakt-sv-SE@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "1a571c53-a05e-483f-ba76-944ce03e405c",
+ "last_modified": 1597452131543
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ru"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "priceru@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "2ca250af-f2ac-4f63-af34-1b1b53fd3b92",
+ "last_modified": 1597452131520
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "pt-PT"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "priberam@search.mozilla.org",
+ "version": "1.2"
+ },
+ "id": "44c5c666-422b-4fc2-b9e2-cddd0d3b7ccc",
+ "last_modified": 1597452131497
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sr"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "pogodak@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "473fd16b-ed84-4ed1-822c-50ac5d9ee63b",
+ "last_modified": 1597452131475
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "bg"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "pazaruvaj@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "6752ecbe-99cc-4ce9-90db-31c8d9e7c506",
+ "last_modified": 1597452131452
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "cy"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "palasprint@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "1f5075fa-ed75-4561-919f-3fa6e1158bf7",
+ "last_modified": 1597452131429
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ru"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "ozonru@search.mozilla.org",
+ "version": "1.2"
+ },
+ "id": "954cc2fe-72f5-4360-b200-ab455c5ad920",
+ "last_modified": 1597452131407
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "et"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "osta-ee@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "e4e7b227-f6e6-49bf-840a-a7b7601e1a92",
+ "last_modified": 1597452131384
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ja-JP-macos",
+ "jp"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "oshiete-goo@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "ba06b66e-b083-42f9-96ca-06beb7df003b",
+ "last_modified": 1597452131360
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "bs"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "olx@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "0a2b2d3b-18d7-425d-b852-319cafe49d22",
+ "last_modified": 1597452131338
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sl"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "odpiralni@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "7e85688f-5f3e-4dce-a624-6a80ea792a39",
+ "last_modified": 1597452131315
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "et"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "neti-ee@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "c7cd702e-9049-4a75-823c-6ccd7ad2b86f",
+ "last_modified": 1597452131292
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ko"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "naver-kr@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "af1943a3-75e1-4429-8a95-43675686786c",
+ "last_modified": 1597452131271
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sl"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "najdi-si@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "fda60f56-ac34-410a-8e74-1b2ba0dbaeaa",
+ "last_modified": 1597452131248
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "he"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "morfix-dic@search.mozilla.org",
+ "version": "1.1"
+ },
+ "id": "2950bf4a-450f-47cd-8988-1d9d73c10300",
+ "last_modified": 1597452131225
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "pt-BR"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "mercadolivre@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "393eed85-f54c-453c-9df3-d5351473a2d0",
+ "last_modified": 1597452131204
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "es-AR"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "ar"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "es-CL"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "cl"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "es-MX"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "mx"
+ ]
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "mercadolibre@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "58ccc938-9b28-43fa-99c8-8fb2afaf0531",
+ "last_modified": 1597452131181
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "fy-NL"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "fy-NL"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "nl"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "nl"
+ ]
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "marktplaats@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "5e341152-6dc1-4357-80cb-8c2d615ec5dc",
+ "last_modified": 1597452131158
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "cs"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "mapy-cz@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "bcee8873-4644-44c1-babf-b35be366f4f7",
+ "last_modified": 1597452131136
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "th"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "longdo@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "c64fefb6-61b5-49fe-8148-1470fa586c21",
+ "last_modified": 1597452131091
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "hy-AM"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "list-am@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "2e099aaa-b949-4038-8595-69678b09c46d",
+ "last_modified": 1597452131070
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "de",
+ "dsb",
+ "hsb",
+ "rm"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "leo_ende_de@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "4db2ab80-c651-405b-88ba-1b30396a5d23",
+ "last_modified": 1597452131047
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "kn"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "kannadastore@search.mozilla.org",
+ "version": "1.2"
+ },
+ "id": "8cb31936-c2da-47b6-8acc-15e2d48d2362",
+ "last_modified": 1597452131024
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "uk"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "hotline-ua@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "5b2895b4-afb4-452d-bc8f-4b3752448fba",
+ "last_modified": 1597452131003
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "cs"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "heureka-cz@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "dfc28b2a-40ac-4772-bca3-8b090ab8a05e",
+ "last_modified": 1597452130980
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "nn-NO",
+ "nb-NO"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "gulesider-NO@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "311b0b99-0619-446f-ad7c-695e531ec000",
+ "last_modified": 1597452130957
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "br"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "freelang@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "e72ce961-ea88-4296-ac41-745d75c14363",
+ "last_modified": 1597452130936
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "kk"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "flip@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "0b17f642-5519-4e5b-89bb-71e16e3e0763",
+ "last_modified": 1597452130913
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "gd"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "faclair-beag@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "2b046c0d-3cc6-4639-8454-2d2ea024705b",
+ "last_modified": 1597452130891
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "hr"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "eudict@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "1bf9f430-9b92-4c3b-a2c1-0a7edddc1f28",
+ "last_modified": 1597452130869
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "et"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "eki-ee@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "7c60a125-37c2-48f1-b541-86fe070b4388",
+ "last_modified": 1597452130847
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "de"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "ecosia@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "e7083870-11cf-4c2b-8843-67b3e098f474",
+ "last_modified": 1597452130824
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "es-AR",
+ "es-CL",
+ "es-ES"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "drae@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "fcf39b52-b59d-42a5-b1a8-4361159b428d",
+ "last_modified": 1597452130803
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ca",
+ "ca-valencia"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "diec2@search.mozilla.org",
+ "version": "1.2"
+ },
+ "id": "b88830cd-705d-492a-a28c-742abfa9334b",
+ "last_modified": 1597452130780
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ko"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "daum-kr@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "2dc000ee-a78b-4e78-91af-ac76b79bac47",
+ "last_modified": 1597452130756
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "vi"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "coccoc@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "cd8d215b-6c81-439b-bc16-dab6bae8188b",
+ "last_modified": 1597452130735
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "en-GB"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "chambers-en-GB@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "7047c29e-7ad4-49db-adb9-6c135e6c59f8",
+ "last_modified": 1597452130712
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sl"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "ceneji@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "c0fe16a1-6d66-48a2-bc54-ceb9a78754ce",
+ "last_modified": 1597452130688
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "fy-NL"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "fy-NL"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "nl"
+ ]
+ }
+ },
+ "webExtension": {
+ "locales": [
+ "nl"
+ ]
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "bolcom@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "adc06075-02c9-4d8d-88ab-bccd1b843184",
+ "last_modified": 1597452130667
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "nb-NO",
+ "nn-NO"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "bok-NO@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "dc33bc2b-758b-41fe-804c-e9894aea9cc1",
+ "last_modified": 1597452130644
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "gd"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "bbc-alba@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "614c27ea-1537-4db0-ac1d-b873732bde57",
+ "last_modified": 1597452130621
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sk"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "azet-sk@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "17835df2-e2b8-4ca8-91bc-a45299bdcae5",
+ "last_modified": 1597452130600
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "az"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "azerdict@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "85d4f0c7-ace1-4e67-9e16-38db2aebf84b",
+ "last_modified": 1597452130577
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sk"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "atlas-sk@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "bb87e317-4ba3-458e-9b64-d4459e61b001",
+ "last_modified": 1597452130554
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "pl"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "allegro-pl@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "9933195c-160e-41bb-984b-019137687d48",
+ "last_modified": 1597452130533
+ },
+ {
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "sv-SE"
+ ]
+ }
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "allaannonser-sv-SE@search.mozilla.org",
+ "version": "1.2"
+ },
+ "id": "7011ae79-112a-494a-834b-857b66e444c0",
+ "last_modified": 1597452130511
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "field-keywords",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "ie",
+ "value": "{inputEncoding}"
+ },
+ {
+ "name": "mode",
+ "value": "blended"
+ }
+ ]
+ },
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "as",
+ "bn",
+ "bn-IN",
+ "kn",
+ "gu-IN",
+ "mai",
+ "ml",
+ "mr",
+ "or",
+ "pa-IN",
+ "ta",
+ "te",
+ "ur"
+ ]
+ }
+ },
+ "telemetryId": "amazon-in",
+ "webExtension": {
+ "locales": [
+ "in"
+ ]
+ }
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "field-keywords",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "ie",
+ "value": "{inputEncoding}"
+ },
+ {
+ "name": "mode",
+ "value": "blended"
+ },
+ {
+ "name": "sourceid",
+ "value": "Mozilla-search"
+ }
+ ]
+ },
+ "included": {
+ "locales": {
+ "matches": [
+ "br",
+ "ff",
+ "fr",
+ "son",
+ "wo"
+ ]
+ }
+ },
+ "telemetryId": "amazon-france",
+ "webExtension": {
+ "locales": [
+ "france"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "br",
+ "ff",
+ "fr",
+ "son",
+ "wo"
+ ]
+ },
+ "regions": [
+ "ca"
+ ]
+ },
+ "telemetryId": "amazon-ca",
+ "webExtension": {
+ "locales": [
+ "ca"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "en-CA"
+ ]
+ }
+ },
+ "telemetryId": "amazon-ca",
+ "webExtension": {
+ "locales": [
+ "ca"
+ ]
+ }
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "field-keywords",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "ie",
+ "value": "{inputEncoding}"
+ },
+ {
+ "name": "mode",
+ "value": "blended"
+ },
+ {
+ "name": "sourceid",
+ "value": "Mozilla-search"
+ }
+ ]
+ },
+ "included": {
+ "locales": {
+ "matches": [
+ "ja-JP-macos",
+ "ja"
+ ]
+ }
+ },
+ "telemetryId": "amazon-jp",
+ "webExtension": {
+ "locales": [
+ "jp"
+ ]
+ }
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "field-keywords",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "ie",
+ "value": "{inputEncoding}"
+ },
+ {
+ "name": "mode",
+ "value": "blended"
+ },
+ {
+ "name": "sourceid",
+ "value": "Mozilla-search"
+ }
+ ]
+ },
+ "included": {
+ "locales": {
+ "matches": [
+ "it",
+ "lij"
+ ]
+ }
+ },
+ "telemetryId": "amazon-it",
+ "webExtension": {
+ "locales": [
+ "it"
+ ]
+ }
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "field-keywords",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "ie",
+ "value": "{inputEncoding}"
+ },
+ {
+ "name": "mode",
+ "value": "blended"
+ },
+ {
+ "name": "sourceid",
+ "value": "Mozilla-search"
+ }
+ ]
+ },
+ "included": {
+ "locales": {
+ "matches": [
+ "de",
+ "dsb",
+ "hsb"
+ ]
+ }
+ },
+ "telemetryId": "amazon-de",
+ "webExtension": {
+ "locales": [
+ "de"
+ ]
+ }
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "field-keywords",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "ie",
+ "value": "{inputEncoding}"
+ },
+ {
+ "name": "mode",
+ "value": "blended"
+ },
+ {
+ "name": "sourceid",
+ "value": "Mozilla-search"
+ }
+ ]
+ },
+ "included": {
+ "locales": {
+ "matches": [
+ "cy",
+ "da",
+ "el",
+ "en-GB",
+ "eu",
+ "ga-IE",
+ "gd",
+ "gl",
+ "hr",
+ "nb-NO",
+ "nn-NO",
+ "pt-PT",
+ "sq",
+ "sr"
+ ]
+ }
+ },
+ "telemetryId": "amazon-en-GB",
+ "webExtension": {
+ "locales": [
+ "en-GB"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "cy",
+ "da",
+ "el",
+ "en-GB",
+ "eu",
+ "ga-IE",
+ "gd",
+ "gl",
+ "hr",
+ "nb-NO",
+ "nn-NO",
+ "pt-PT",
+ "sq",
+ "sr"
+ ]
+ },
+ "regions": [
+ "au"
+ ]
+ },
+ "telemetryId": "amazon-au",
+ "webExtension": {
+ "locales": [
+ "au"
+ ]
+ }
+ }
+ ],
+ "orderHint": 500,
+ "webExtension": {
+ "id": "amazon@search.mozilla.org",
+ "version": "1.1"
+ },
+ "id": "968c66a0-0d32-4bdb-a132-66d0e7dead54",
+ "last_modified": 1597452130421
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "field-keywords",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "ie",
+ "value": "{inputEncoding}"
+ },
+ {
+ "name": "mode",
+ "value": "blended"
+ },
+ {
+ "name": "sourceid",
+ "value": "Mozilla-search"
+ }
+ ]
+ },
+ "appliesTo": [
+ {
+ "included": {
+ "regions": [
+ "default"
+ ]
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ach",
+ "af",
+ "ar",
+ "az",
+ "bg",
+ "cak",
+ "en-US",
+ "eo",
+ "es-AR",
+ "fa",
+ "gn",
+ "hy-AM",
+ "ia",
+ "is",
+ "ka",
+ "km",
+ "lt",
+ "mk",
+ "ms",
+ "my",
+ "ro",
+ "si",
+ "th",
+ "tl",
+ "trs",
+ "uz"
+ ]
+ }
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ach",
+ "af",
+ "ar",
+ "az",
+ "bg",
+ "cak",
+ "en-US",
+ "eo",
+ "es-AR",
+ "fa",
+ "gn",
+ "hy-AM",
+ "ia",
+ "is",
+ "ka",
+ "km",
+ "lt",
+ "mk",
+ "ms",
+ "my",
+ "ro",
+ "si",
+ "th",
+ "tl",
+ "trs",
+ "uz"
+ ]
+ },
+ "regions": [
+ "au"
+ ]
+ },
+ "telemetryId": "amazon-au",
+ "webExtension": {
+ "id": "amazon@search.mozilla.org",
+ "locales": [
+ "au"
+ ],
+ "version": "1.1"
+ }
+ },
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ach",
+ "af",
+ "ar",
+ "az",
+ "bg",
+ "cak",
+ "en-US",
+ "eo",
+ "es-AR",
+ "fa",
+ "gn",
+ "hy-AM",
+ "ia",
+ "is",
+ "ka",
+ "km",
+ "lt",
+ "mk",
+ "ms",
+ "my",
+ "ro",
+ "si",
+ "th",
+ "tl",
+ "trs",
+ "uz"
+ ]
+ },
+ "regions": [
+ "ca"
+ ]
+ },
+ "telemetryId": "amazon-ca",
+ "webExtension": {
+ "id": "amazon@search.mozilla.org",
+ "locales": [
+ "ca"
+ ],
+ "version": "1.1"
+ }
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "field-keywords",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "ie",
+ "value": "{inputEncoding}"
+ },
+ {
+ "name": "mode",
+ "value": "blended"
+ },
+ {
+ "name": "sourceid",
+ "value": "Mozilla-search"
+ }
+ ]
+ },
+ "included": {
+ "locales": {
+ "matches": [
+ "ach",
+ "af",
+ "ar",
+ "az",
+ "bg",
+ "cak",
+ "en-US",
+ "eo",
+ "es-AR",
+ "fa",
+ "gn",
+ "hy-AM",
+ "ia",
+ "is",
+ "ka",
+ "km",
+ "lt",
+ "mk",
+ "ms",
+ "my",
+ "ro",
+ "si",
+ "th",
+ "tl",
+ "trs",
+ "uz"
+ ]
+ },
+ "regions": [
+ "fr"
+ ]
+ },
+ "telemetryId": "amazon-france",
+ "webExtension": {
+ "id": "amazon@search.mozilla.org",
+ "locales": [
+ "france"
+ ],
+ "version": "1.1"
+ }
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "field-keywords",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "ie",
+ "value": "{inputEncoding}"
+ },
+ {
+ "name": "mode",
+ "value": "blended"
+ },
+ {
+ "name": "sourceid",
+ "value": "Mozilla-search"
+ }
+ ]
+ },
+ "included": {
+ "locales": {
+ "matches": [
+ "ach",
+ "af",
+ "ar",
+ "az",
+ "bg",
+ "cak",
+ "en-US",
+ "eo",
+ "es-AR",
+ "fa",
+ "gn",
+ "hy-AM",
+ "ia",
+ "is",
+ "ka",
+ "km",
+ "lt",
+ "mk",
+ "ms",
+ "my",
+ "ro",
+ "si",
+ "th",
+ "tl",
+ "trs",
+ "uz"
+ ]
+ },
+ "regions": [
+ "gb"
+ ]
+ },
+ "telemetryId": "amazon-en-GB",
+ "webExtension": {
+ "id": "amazon@search.mozilla.org",
+ "locales": [
+ "en-GB"
+ ],
+ "version": "1.1"
+ }
+ }
+ ],
+ "orderHint": 500,
+ "telemetryId": "amazondotcom",
+ "webExtension": {
+ "id": "amazondotcom@search.mozilla.org",
+ "version": "1.1"
+ },
+ "id": "5eb7e179-c11d-4029-99b7-bc7ea1467d46",
+ "last_modified": 1597452130399
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "wd",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "tn",
+ "value": "monline_7_dg"
+ },
+ {
+ "name": "ie",
+ "value": "utf-8"
+ }
+ ],
+ "suggestUrlGetParams": [
+ {
+ "name": "wd",
+ "value": "{searchTerms}"
+ },
+ {
+ "name": "tn",
+ "value": "monline_7_dg"
+ },
+ {
+ "name": "ie",
+ "value": "utf-8"
+ },
+ {
+ "name": "action",
+ "value": "opensearch"
+ }
+ ]
+ },
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "zh-CN"
+ ]
+ }
+ }
+ },
+ {
+ "default": "yes",
+ "included": {
+ "locales": {
+ "matches": [
+ "zh-CN"
+ ]
+ },
+ "regions": [
+ "cn"
+ ]
+ }
+ }
+ ],
+ "telemetryId": "baidu",
+ "webExtension": {
+ "id": "baidu@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "59f371ee-05cc-4c9e-8961-27fe1fa4cbc2",
+ "last_modified": 1597452130376
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "q",
+ "value": "{searchTerms}"
+ }
+ ]
+ },
+ "appliesTo": [
+ {
+ "included": {
+ "locales": {
+ "matches": [
+ "ach",
+ "af",
+ "an",
+ "ar",
+ "ast",
+ "az",
+ "ca",
+ "ca-valencia",
+ "cak",
+ "da",
+ "de",
+ "dsb",
+ "el",
+ "eo",
+ "es-CL",
+ "es-ES",
+ "es-MX",
+ "eu",
+ "fa",
+ "ff",
+ "fi",
+ "fr",
+ "fy-NL",
+ "gn",
+ "gu-IN",
+ "hi-IN",
+ "hr",
+ "hsb",
+ "ia",
+ "is",
+ "it",
+ "ja-JP-macos",
+ "ja",
+ "ka",
+ "kab",
+ "km",
+ "kn",
+ "lij",
+ "lo",
+ "lt",
+ "mai",
+ "mk",
+ "ml",
+ "ms",
+ "my",
+ "nb-NO",
+ "ne-NP",
+ "nl",
+ "nn-NO",
+ "oc",
+ "or",
+ "pa-IN",
+ "pt-BR",
+ "rm",
+ "ro",
+ "son",
+ "sq",
+ "sr",
+ "sv-SE",
+ "th",
+ "tl",
+ "trs",
+ "uk",
+ "ur",
+ "uz",
+ "wo",
+ "xh",
+ "zh-CN"
+ ],
+ "startsWith": [
+ "bn",
+ "en"
+ ]
+ }
+ }
+ },
+ {
+ "included": {
+ "regions": [
+ "default"
+ ]
+ }
+ }
+ ],
+ "webExtension": {
+ "id": "bing@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "d6b19d48-c263-49f9-9f5b-72fb5a3824bc",
+ "last_modified": 1597452130353
+ },
+ {
+ "params": {
+ "searchUrlGetParams": [
+ {
+ "name": "q",
+ "value": "{searchTerms}"
+ }
+ ]
+ },
+ "appliesTo": [
+ {
+ "default": "yes-if-no-other",
+ "included": {
+ "everywhere": true
+ }
+ }
+ ],
+ "orderHint": 1000,
+ "telemetryId": "google",
+ "webExtension": {
+ "id": "google@search.mozilla.org",
+ "version": "1.0"
+ },
+ "id": "6158e467-c0d3-48e8-a5cf-a2102b7f9456",
+ "last_modified": 1597452130330
+ }
+ ]
+}
diff -Nru thunderbird-91.7.0+build2/comm/mail/base/content/mailCommands.js thunderbird-91.8.1+build1/comm/mail/base/content/mailCommands.js
--- thunderbird-91.7.0+build2/comm/mail/base/content/mailCommands.js 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/base/content/mailCommands.js 2022-04-15 07:49:21.000000000 +0000
@@ -237,7 +237,8 @@
Ci.nsIMsgCompType.Reply,
Ci.nsIMsgCompType.ReplyAll,
Ci.nsIMsgCompType.ReplyToSender,
- Ci.nsIMsgCompType.ReplyToGroup,
+ // Author's address doesn't matter for followup to a newsgroup.
+ // Ci.nsIMsgCompType.ReplyToGroup,
Ci.nsIMsgCompType.ReplyToSenderAndGroup,
Ci.nsIMsgCompType.ReplyWithTemplate,
Ci.nsIMsgCompType.ReplyToList,
diff -Nru thunderbird-91.7.0+build2/comm/mail/base/content/msgMail3PaneWindow.js thunderbird-91.8.1+build1/comm/mail/base/content/msgMail3PaneWindow.js
--- thunderbird-91.7.0+build2/comm/mail/base/content/msgMail3PaneWindow.js 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/base/content/msgMail3PaneWindow.js 2022-04-15 07:49:21.000000000 +0000
@@ -1211,6 +1211,10 @@
Services.tm.dispatchToMainThread(loadExtraTabs);
SessionStoreManager._restored = true;
Services.obs.notifyObservers(window, "mail-tabs-session-restored");
+ // Notify observer to resolve the browserStartupPromise, which is used for the
+ // delayed background startup of WebExtensions.
+ Services.obs.notifyObservers(window, "extensions-late-startup");
+
return !!state;
}
diff -Nru thunderbird-91.7.0+build2/comm/mail/base/test/unit/test_oauth_migration.js thunderbird-91.8.1+build1/comm/mail/base/test/unit/test_oauth_migration.js
--- thunderbird-91.7.0+build2/comm/mail/base/test/unit/test_oauth_migration.js 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/base/test/unit/test_oauth_migration.js 2022-04-15 07:49:21.000000000 +0000
@@ -0,0 +1,301 @@
+/* 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/. */
+
+/**
+ * Test migrating Yahoo/AOL users to OAuth2, since "normal password" is going away
+ * on October 20, 2020.
+ */
+
+var { MailMigrator } = ChromeUtils.import(
+ "resource:///modules/MailMigrator.jsm"
+);
+var { localAccountUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/LocalAccountUtils.jsm"
+);
+var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+var gAccountList = [
+ // POP Yahoo account + Yahoo Server.
+ {
+ type: "pop3",
+ port: 1234,
+ user: "pop3user",
+ password: "pop3password",
+ hostname: "pop3.mail.yahoo.com",
+ socketType: Ci.nsMsgSocketType.plain,
+ authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
+ smtpServers: [
+ {
+ port: 3456,
+ user: "imapout",
+ password: "imapoutpassword",
+ isDefault: true,
+ hostname: "smtp.mail.yahoo.com",
+ socketType: Ci.nsMsgSocketType.alwaysSTARTTLS,
+ authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
+ },
+ ],
+ },
+ // IMAP Yahoo account + Google Server.
+ {
+ type: "imap",
+ port: 2345,
+ user: "imapuser",
+ password: "imappassword",
+ hostname: "imap.mail.yahoo.com",
+ socketType: Ci.nsMsgSocketType.trySTARTTLS,
+ authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
+ smtpServers: [
+ {
+ port: 3456,
+ user: "imapout",
+ password: "imapoutpassword",
+ isDefault: false,
+ hostname: "smtp.gmail.com",
+ socketType: Ci.nsMsgSocketType.alwaysSTARTTLS,
+ authMethod: Ci.nsMsgAuthMethod.passwordEncrypted,
+ },
+ ],
+ },
+ // IMAP Google account + Yahoo Server.
+ {
+ type: "imap",
+ port: 2345,
+ user: "imap2user",
+ password: "imap2password",
+ hostname: "imap.gmail.com",
+ socketType: Ci.nsMsgSocketType.trySTARTTLS,
+ authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
+ smtpServers: [
+ {
+ port: 3456,
+ user: "imapout",
+ password: "imapoutpassword",
+ isDefault: false,
+ hostname: "smtp.mail.yahoo.com",
+ socketType: Ci.nsMsgSocketType.alwaysSTARTTLS,
+ authMethod: Ci.nsMsgAuthMethod.passwordEncrypted,
+ },
+ ],
+ },
+ // IMAP Invalid account + Invalid Server.
+ {
+ type: "imap",
+ port: 2345,
+ user: "imap2user",
+ password: "imap2password",
+ hostname: "imap.mail.foo.invalid",
+ socketType: Ci.nsMsgSocketType.trySTARTTLS,
+ authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
+ smtpServers: [
+ {
+ port: 3456,
+ user: "imapout",
+ password: "imapoutpassword",
+ isDefault: false,
+ hostname: "smtp.mail.foo.invalid",
+ socketType: Ci.nsMsgSocketType.alwaysSTARTTLS,
+ authMethod: Ci.nsMsgAuthMethod.passwordEncrypted,
+ },
+ ],
+ },
+ // AOL IMAP account.
+ {
+ type: "imap",
+ port: 993,
+ user: "aolimap",
+ password: "imap2password",
+ hostname: "imap.aol.com",
+ socketType: Ci.nsMsgSocketType.SSL,
+ authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
+ smtpServers: [
+ {
+ port: 465,
+ user: "imapout2",
+ password: "imapoutpassword2",
+ isDefault: false,
+ hostname: "smtp.aol.com",
+ socketType: Ci.nsMsgSocketType.SSL,
+ authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
+ },
+ ],
+ },
+ // AOL POP3 account.
+ {
+ type: "pop3",
+ port: 995,
+ user: "aolpop3",
+ password: "abc",
+ hostname: "pop.aol.com",
+ socketType: Ci.nsMsgSocketType.SSL,
+ authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
+ smtpServers: [
+ {
+ port: 465,
+ user: "popout",
+ password: "aaa",
+ isDefault: false,
+ hostname: "smtp.aol.com",
+ socketType: Ci.nsMsgSocketType.SSL,
+ authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
+ },
+ ],
+ },
+ // Google POP3 account.
+ {
+ type: "pop3",
+ port: 995,
+ user: "gmailpop3",
+ password: "abc",
+ hostname: "pop.gmail.com",
+ socketType: Ci.nsMsgSocketType.trySTARTTLS,
+ authMethod: Ci.nsMsgAuthMethod.passwordEncrypted,
+ smtpServers: [
+ {
+ port: 465,
+ user: "gmailpopout",
+ password: "aaa",
+ isDefault: true,
+ hostname: "smtp.gmail.com",
+ socketType: Ci.nsMsgAuthMethod.alwaysSTARTTLS,
+ authMethod: Ci.nsMsgAuthMethod.passwordEncrypted,
+ },
+ ],
+ },
+];
+
+// An array of the incoming servers created from the setup_accounts() method.
+var gIncomingServers = [];
+
+// An array of the outgoing servers created from the setup_accounts() method.
+var gOutgoingServers = [];
+
+// An array of the accounts created from the setup_accounts() method.
+var gAccounts = [];
+
+/**
+ * Set up accounts based on the given data.
+ */
+function setup_accounts() {
+ for (let details of gAccountList) {
+ let server = localAccountUtils.create_incoming_server(
+ details.type,
+ details.port,
+ details.user,
+ details.password,
+ details.hostname
+ );
+ server.socketType = details.socketType;
+ server.authMethod = details.authMethod;
+
+ // Add the newly created server to the array for testing.
+ gIncomingServers.push(server);
+
+ let account = MailServices.accounts.FindAccountForServer(server);
+ for (let smtpDetails of details.smtpServers) {
+ let outgoing = localAccountUtils.create_outgoing_server(
+ smtpDetails.port,
+ smtpDetails.user,
+ smtpDetails.password,
+ smtpDetails.hostname
+ );
+ outgoing.socketType = smtpDetails.socketType;
+ outgoing.authMethod = smtpDetails.authMethod;
+ localAccountUtils.associate_servers(
+ account,
+ outgoing,
+ smtpDetails.isDefault
+ );
+
+ // Add the newly created server to the array for testing.
+ gOutgoingServers.push(outgoing);
+
+ // Add the newly created account to the array for cleanup.
+ gAccounts.push(account);
+ }
+ }
+}
+
+function test_oauth_migration() {
+ setup_accounts();
+
+ for (let server of gIncomingServers) {
+ // Confirm all the incoming servers are not using OAuth2 after the setup.
+ Assert.notEqual(
+ server.authMethod,
+ Ci.nsMsgAuthMethod.OAuth2,
+ "Incoming server should not use OAuth2"
+ );
+ }
+
+ for (let server of gOutgoingServers) {
+ // Confirm all the outgoing servers are not using OAuth2 after the setup.
+ Assert.notEqual(
+ server.authMethod,
+ Ci.nsMsgAuthMethod.OAuth2,
+ "Outgoing server should not use OAuth2"
+ );
+ }
+
+ // Run the migration.
+ Services.prefs.setIntPref("mail.ui-rdf.version", 21);
+ MailMigrator._migrateUI();
+
+ for (let server of gIncomingServers) {
+ // Confirm only the correct incoming servers are using OAuth2 after migration.
+ if (
+ !server.hostName.endsWith("mail.yahoo.com") &&
+ !server.hostName.endsWith("aol.com") &&
+ !server.hostName.endsWith("gmail.com")
+ ) {
+ Assert.notEqual(
+ server.authMethod,
+ Ci.nsMsgAuthMethod.OAuth2,
+ `Incoming server ${server.hostName} should not use OAuth2 after migration`
+ );
+ continue;
+ }
+
+ Assert.equal(
+ server.authMethod,
+ Ci.nsMsgAuthMethod.OAuth2,
+ `Incoming server ${server.hostName} should use OAuth2 after migration`
+ );
+ }
+
+ for (let server of gOutgoingServers) {
+ // Confirm only the correct outgoing servers are using OAuth2 after migration.
+ if (
+ !server.hostname.endsWith("mail.yahoo.com") &&
+ !server.hostname.endsWith("aol.com") &&
+ !server.hostname.endsWith("gmail.com")
+ ) {
+ Assert.notEqual(
+ server.authMethod,
+ Ci.nsMsgAuthMethod.OAuth2,
+ `Outgoing server ${server.hostname} should not use OAuth2 after migration`
+ );
+ continue;
+ }
+
+ Assert.equal(
+ server.authMethod,
+ Ci.nsMsgAuthMethod.OAuth2,
+ `Outgoing server ${server.hostname} should use OAuth2 after migration`
+ );
+ }
+
+ // Remove our test accounts and servers to leave the profile clean.
+ for (let account of gAccounts) {
+ MailServices.accounts.removeAccount(account);
+ }
+
+ for (let server of gOutgoingServers) {
+ MailServices.smtp.deleteServer(server);
+ }
+}
+
+function run_test() {
+ test_oauth_migration();
+}
diff -Nru thunderbird-91.7.0+build2/comm/mail/base/test/unit/test_yahoo_oauth_migration.js thunderbird-91.8.1+build1/comm/mail/base/test/unit/test_yahoo_oauth_migration.js
--- thunderbird-91.7.0+build2/comm/mail/base/test/unit/test_yahoo_oauth_migration.js 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/base/test/unit/test_yahoo_oauth_migration.js 1970-01-01 00:00:00.000000000 +0000
@@ -1,278 +0,0 @@
-/* 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/. */
-
-/**
- * Test migrating Yahoo/AOL users to OAuth2, since "normal password" is going away
- * on October 20, 2020.
- */
-
-var { MailMigrator } = ChromeUtils.import(
- "resource:///modules/MailMigrator.jsm"
-);
-var { localAccountUtils } = ChromeUtils.import(
- "resource://testing-common/mailnews/LocalAccountUtils.jsm"
-);
-var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-var gAccountList = [
- // POP Yahoo account + Yahoo Server.
- {
- type: "pop3",
- port: 1234,
- user: "pop3user",
- password: "pop3password",
- hostname: "pop3.mail.yahoo.com",
- socketType: Ci.nsMsgSocketType.plain,
- authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
- smtpServers: [
- {
- port: 3456,
- user: "imapout",
- password: "imapoutpassword",
- isDefault: true,
- hostname: "smtp.mail.yahoo.com",
- socketType: Ci.nsMsgSocketType.alwaysSTARTTLS,
- authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
- },
- ],
- },
- // IMAP Yahoo account + Google Server.
- {
- type: "imap",
- port: 2345,
- user: "imapuser",
- password: "imappassword",
- hostname: "imap.mail.yahoo.com",
- socketType: Ci.nsMsgSocketType.trySTARTTLS,
- authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
- smtpServers: [
- {
- port: 3456,
- user: "imapout",
- password: "imapoutpassword",
- isDefault: false,
- hostname: "smtp.mail.google.com",
- socketType: Ci.nsMsgSocketType.alwaysSTARTTLS,
- authMethod: Ci.nsMsgAuthMethod.passwordEncrypted,
- },
- ],
- },
- // IMAP Google account + Yahoo Server.
- {
- type: "imap",
- port: 2345,
- user: "imap2user",
- password: "imap2password",
- hostname: "imap.mail.google.com",
- socketType: Ci.nsMsgSocketType.trySTARTTLS,
- authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
- smtpServers: [
- {
- port: 3456,
- user: "imapout",
- password: "imapoutpassword",
- isDefault: false,
- hostname: "smtp.mail.yahoo.com",
- socketType: Ci.nsMsgSocketType.alwaysSTARTTLS,
- authMethod: Ci.nsMsgAuthMethod.passwordEncrypted,
- },
- ],
- },
- // IMAP Invalid account + Invalid Server.
- {
- type: "imap",
- port: 2345,
- user: "imap2user",
- password: "imap2password",
- hostname: "imap.mail.foo.invalid",
- socketType: Ci.nsMsgSocketType.trySTARTTLS,
- authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
- smtpServers: [
- {
- port: 3456,
- user: "imapout",
- password: "imapoutpassword",
- isDefault: false,
- hostname: "smtp.mail.foo.invalid",
- socketType: Ci.nsMsgSocketType.alwaysSTARTTLS,
- authMethod: Ci.nsMsgAuthMethod.passwordEncrypted,
- },
- ],
- },
- // AOL IMAP account.
- {
- type: "imap",
- port: 993,
- user: "aolimap",
- password: "imap2password",
- hostname: "imap.aol.com",
- socketType: Ci.nsMsgSocketType.SSL,
- authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
- smtpServers: [
- {
- port: 465,
- user: "imapout2",
- password: "imapoutpassword2",
- isDefault: false,
- hostname: "smtp.aol.com",
- socketType: Ci.nsMsgSocketType.SSL,
- authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
- },
- ],
- },
- // AOL POP3 account.
- {
- type: "pop3",
- port: 995,
- user: "aolpop3",
- password: "abc",
- hostname: "pop.aol.com",
- socketType: Ci.nsMsgSocketType.SSL,
- authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
- smtpServers: [
- {
- port: 465,
- user: "popout",
- password: "aaa",
- isDefault: false,
- hostname: "smtp.aol.com",
- socketType: Ci.nsMsgSocketType.SSL,
- authMethod: Ci.nsMsgAuthMethod.passwordCleartext,
- },
- ],
- },
-];
-
-// An array of the incoming servers created from the setup_accounts() method.
-var gIncomingServers = [];
-
-// An array of the outgoing servers created from the setup_accounts() method.
-var gOutgoingServers = [];
-
-// An array of the accounts created from the setup_accounts() method.
-var gAccounts = [];
-
-/**
- * Set up accounts based on the given data.
- */
-function setup_accounts() {
- for (let details of gAccountList) {
- let server = localAccountUtils.create_incoming_server(
- details.type,
- details.port,
- details.user,
- details.password,
- details.hostname
- );
- server.socketType = details.socketType;
- server.authMethod = details.authMethod;
-
- // Add the newly created server to the array for testing.
- gIncomingServers.push(server);
-
- let account = MailServices.accounts.FindAccountForServer(server);
- for (let smtpDetails of details.smtpServers) {
- let outgoing = localAccountUtils.create_outgoing_server(
- smtpDetails.port,
- smtpDetails.user,
- smtpDetails.password,
- smtpDetails.hostname
- );
- outgoing.socketType = smtpDetails.socketType;
- outgoing.authMethod = smtpDetails.authMethod;
- localAccountUtils.associate_servers(
- account,
- outgoing,
- smtpDetails.isDefault
- );
-
- // Add the newly created server to the array for testing.
- gOutgoingServers.push(outgoing);
-
- // Add the newly created account to the array for cleanup.
- gAccounts.push(account);
- }
- }
-}
-
-function test_yahoo_oauth_migration() {
- setup_accounts();
-
- for (let server of gIncomingServers) {
- // Confirm all the incoming servers are not using OAuth2 after the setup.
- Assert.notEqual(
- server.authMethod,
- Ci.nsMsgAuthMethod.OAuth2,
- "Incoming server doesn't use OAuth2"
- );
- }
-
- for (let server of gOutgoingServers) {
- // Confirm all the outgoing servers are not using OAuth2 after the setup.
- Assert.notEqual(
- server.authMethod,
- Ci.nsMsgAuthMethod.OAuth2,
- "Outgoing server doesn't use OAuth2"
- );
- }
-
- // Run the migration.
- Services.prefs.setIntPref("mail.ui-rdf.version", 21);
- MailMigrator._migrateUI();
-
- for (let server of gIncomingServers) {
- // Confirm only the correct incoming servers are using OAuth2 after migration.
- if (
- !server.hostName.endsWith("mail.yahoo.com") &&
- !server.hostName.endsWith("aol.com")
- ) {
- Assert.notEqual(
- server.authMethod,
- Ci.nsMsgAuthMethod.OAuth2,
- `Incoming server ${server.hostName} doesn't use OAuth2 after migration`
- );
- continue;
- }
-
- Assert.equal(
- server.authMethod,
- Ci.nsMsgAuthMethod.OAuth2,
- `Incoming server ${server.hostName} should use OAuth2 after migration`
- );
- }
-
- for (let server of gOutgoingServers) {
- // Confirm only the correct outgoing servers are using OAuth2 after migration.
- if (
- !server.hostname.endsWith("mail.yahoo.com") &&
- !server.hostname.endsWith("aol.com")
- ) {
- Assert.notEqual(
- server.authMethod,
- Ci.nsMsgAuthMethod.OAuth2,
- `Outgoing server ${server.hostname} doesn't use OAuth2 after migration`
- );
- continue;
- }
-
- Assert.equal(
- server.authMethod,
- Ci.nsMsgAuthMethod.OAuth2,
- `Outgoing server ${server.hostname} should use OAuth2 after migration`
- );
- }
-
- // Remove our test accounts and servers to leave the profile clean.
- for (let account of gAccounts) {
- MailServices.accounts.removeAccount(account);
- }
-
- for (let server of gOutgoingServers) {
- MailServices.smtp.deleteServer(server);
- }
-}
-
-function run_test() {
- test_yahoo_oauth_migration();
-}
diff -Nru thunderbird-91.7.0+build2/comm/mail/base/test/unit/xpcshell.ini thunderbird-91.8.1+build1/comm/mail/base/test/unit/xpcshell.ini
--- thunderbird-91.7.0+build2/comm/mail/base/test/unit/xpcshell.ini 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/base/test/unit/xpcshell.ini 2022-04-15 07:49:21.000000000 +0000
@@ -18,7 +18,7 @@
run-sequentially = Avoid bustage.
[test_windows_font_migration.js]
skip-if = os != "win"
-[test_yahoo_oauth_migration.js]
+[test_oauth_migration.js]
[test_mailGlue_distribution.js]
[include:xpcshell_maildir.ini]
diff -Nru thunderbird-91.7.0+build2/comm/mail/components/compose/content/MsgComposeCommands.js thunderbird-91.8.1+build1/comm/mail/components/compose/content/MsgComposeCommands.js
--- thunderbird-91.7.0+build2/comm/mail/components/compose/content/MsgComposeCommands.js 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/components/compose/content/MsgComposeCommands.js 2022-04-15 07:49:21.000000000 +0000
@@ -6724,7 +6724,7 @@
document.l10n.setAttributes(
document.getElementById("attachmentBucketCount"),
- "attachment-bucket-count",
+ "attachment-bucket-count-value",
{ count }
);
diff -Nru thunderbird-91.7.0+build2/comm/mail/components/MessengerContentHandler.jsm thunderbird-91.8.1+build1/comm/mail/components/MessengerContentHandler.jsm
--- thunderbird-91.7.0+build2/comm/mail/components/MessengerContentHandler.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/components/MessengerContentHandler.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -296,6 +296,8 @@
// The URI might be passed as the argument to the file parameter
uri = cmdLine.handleFlagWithParam("file", false);
+ // macOS passes `-url mid:` into the command line, drop the -url flag.
+ cmdLine.handleFlag("url", false);
var count = cmdLine.length;
if (count) {
@@ -346,6 +348,8 @@
}
}
if (uri) {
+ // Check for protocols first then look at the file ending.
+ // Protocols are able to contain file endings like '.ics'.
if (/^https?:/i.test(uri)) {
Cc["@mozilla.org/newsblog-feed-downloader;1"]
.getService(Ci.nsINewsBlogFeedDownloader)
@@ -448,6 +452,31 @@
Services.prompt.alert(null, title, message);
}
+ } else if (/^webcals?:\/\//i.test(uri)) {
+ Services.ww.openWindow(
+ null,
+ "chrome://calendar/content/calendar-creation.xhtml",
+ "_blank",
+ "chrome,titlebar,modal,centerscreen",
+ Services.io.newURI(uri)
+ );
+ } else if (/^mid:/i.test(uri)) {
+ let { MailUtils } = ChromeUtils.import(
+ "resource:///modules/MailUtils.jsm"
+ );
+ MailUtils.openMessageByMessageId(uri.slice(4));
+ } else if (uri.toLowerCase().endsWith(".ics")) {
+ // An .ics calendar file! Open the ics file dialog.
+ let file = cmdLine.resolveFile(uri);
+ if (file.exists() && file.fileSize > 0) {
+ Services.ww.openWindow(
+ null,
+ "chrome://calendar/content/calendar-ics-file-dialog.xhtml",
+ "_blank",
+ "chrome,titlebar,modal,centerscreen",
+ file
+ );
+ }
} else if (uri.toLowerCase().endsWith(".vcf")) {
// A VCard! Be smart and open the "add contact" dialog.
let file = cmdLine.resolveFile(uri);
@@ -489,31 +518,6 @@
}
);
}
- } else if (uri.toLowerCase().endsWith(".ics")) {
- // An .ics calendar file! Open the ics file dialog.
- let file = cmdLine.resolveFile(uri);
- if (file.exists() && file.fileSize > 0) {
- Services.ww.openWindow(
- null,
- "chrome://calendar/content/calendar-ics-file-dialog.xhtml",
- "_blank",
- "chrome,titlebar,modal,centerscreen",
- file
- );
- }
- } else if (/^webcals?:\/\//i.test(uri)) {
- Services.ww.openWindow(
- null,
- "chrome://calendar/content/calendar-creation.xhtml",
- "_blank",
- "chrome,titlebar,modal,centerscreen",
- Services.io.newURI(uri)
- );
- } else if (/^mid:/i.test(uri)) {
- let { MailUtils } = ChromeUtils.import(
- "resource:///modules/MailUtils.jsm"
- );
- MailUtils.openMessageByMessageId(uri.slice(4));
} else {
// This must be a regular filename. Use it to create a new message with attachment.
let msgParams = Cc[
diff -Nru thunderbird-91.7.0+build2/comm/mail/config/version_display.txt thunderbird-91.8.1+build1/comm/mail/config/version_display.txt
--- thunderbird-91.7.0+build2/comm/mail/config/version_display.txt 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/config/version_display.txt 2022-04-15 07:49:21.000000000 +0000
@@ -1 +1 @@
-91.7.0
+91.8.1
diff -Nru thunderbird-91.7.0+build2/comm/mail/config/version.txt thunderbird-91.8.1+build1/comm/mail/config/version.txt
--- thunderbird-91.7.0+build2/comm/mail/config/version.txt 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/config/version.txt 2022-04-15 07:49:21.000000000 +0000
@@ -1 +1 @@
-91.7.0
+91.8.1
diff -Nru thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/modules/keyRing.jsm thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/modules/keyRing.jsm
--- thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/modules/keyRing.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/modules/keyRing.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -694,8 +694,8 @@
minimizeKey,
limitedUids,
importSecret,
- passCB,
allowPermissiveFallbackWithPrompt,
+ passCB,
acceptance
)
);
diff -Nru thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/modules/RNP.jsm thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/modules/RNP.jsm
--- thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/modules/RNP.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/modules/RNP.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -644,14 +644,53 @@
return true;
},
+ /*
+ // We don't need these functions currently, but it's helpful
+ // information that I'd like to keep around as documentation.
+
+ isUInt64WithinBounds(val) {
+ // JS integers are limited to 53 bits precision.
+ // Numbers smaller than 2^53 -1 are safe to use.
+ // (For comparison, that's 8192 TB or 8388608 GB).
+ const num53BitsMinus1 = ctypes.UInt64("0x1fffffffffffff");
+ return ctypes.UInt64.compare(val, num53BitsMinus1) < 0;
+ },
+
+ isUInt64Max(val) {
+ // 2^64-1, 18446744073709551615
+ const max = ctypes.UInt64("0xffffffffffffffff");
+ return ctypes.UInt64.compare(val, max) == 0;
+ },
+ */
+
isBadKey(handle) {
- let validTill = new ctypes.uint32_t();
- if (RNPLib.rnp_key_valid_till(handle, validTill.address())) {
- throw new Error("rnp_key_valid_till failed");
+ let validTill64 = new ctypes.uint64_t();
+ if (RNPLib.rnp_key_valid_till64(handle, validTill64.address())) {
+ throw new Error("rnp_key_valid_till64 failed");
+ }
+
+ // For the purpose of this function, we define bad as: there isn't
+ // any valid self-signature on the key, and thus the key should
+ // be completely avoided.
+ // In this scenario, zero is returned. In other words,
+ // if a non-zero value is returned, we know the key isn't completely
+ // bad according to our definition.
+
+ // ctypes.uint64_t().value is of type ctypes.UInt64
+
+ if (ctypes.UInt64.compare(validTill64.value, ctypes.UInt64("0")) > 0) {
+ return false;
}
- // A bad key is invalid for any time
- return !validTill.value;
+ // If zero was returned, it could potentially have been revoked.
+ // If it was revoked, we don't treat is as generally bad,
+ // to allow importing it and to consume the revocation information.
+ // If the key was not revoked, then treat it as a bad key.
+ let key_revoked = new ctypes.bool();
+ if (RNPLib.rnp_key_is_revoked(handle, key_revoked.address())) {
+ throw new Error("rnp_key_is_revoked failed");
+ }
+ return !key_revoked.value;
},
isPrimaryUid(uid_handle) {
@@ -726,6 +765,10 @@
RNPLib.ffi,
"0x" + keyId
);
+ if (handle.isNull()) {
+ return null;
+ }
+
let mainKeyObj = {};
this.getKeyInfoFromHandle(
RNPLib.ffi,
@@ -1925,20 +1968,17 @@
// We allow importing, if any of the following is true
// - it contains a secret key
// - it contains at least one user ID
+ // - it is an update for an existing key (possibly new validity/revocation)
if (k.userIds.length == 0 && !k.secretAvailable) {
- continue;
- // TODO: bug 1634524 requests that we import keys without user
- // ID, if we already have this key.
- // It hasn't been tested yet how well this works.
- /*
- let existingKey = await this.getKeyHandleByIdentifier(RNPLib.ffi, "0x" + k.fpr);
+ let existingKey = await this.getKeyHandleByIdentifier(
+ RNPLib.ffi,
+ "0x" + k.fpr
+ );
if (existingKey.isNull()) {
continue;
- } else {
- RNPLib.rnp_key_handle_destroy(existingKey);
}
- */
+ RNPLib.rnp_key_handle_destroy(existingKey);
}
let impKey = await this.getKeyHandleByIdentifier(tempFFI, fprStr);
@@ -2178,7 +2218,18 @@
if (RNPLib.rnp_key_allows_usage(key, usage, allowed.address())) {
throw new Error("rnp_key_allows_usage failed");
}
- return allowed.value;
+ if (!allowed.value) {
+ return false;
+ }
+
+ if (usage != str_sign) {
+ return true;
+ }
+
+ return (
+ RNPLib.getSecretAvailableFromHandle(key) &&
+ RNPLib.isSecretKeyMaterialAvailable(key)
+ );
},
getSuitableSubkey(primary, usage) {
@@ -2406,7 +2457,7 @@
let use_sub = this.getSuitableSubkey(senderKey, str_sign);
if (!use_sub && !this.isKeyUsableFor(senderKey, str_sign)) {
- throw new Error("no suitable subkey found for " + str_sign);
+ throw new Error("no suitable (sub)key found for " + str_sign);
}
if (args.encrypt) {
@@ -2855,6 +2906,63 @@
return result;
},
+ /**
+ * The RNP library may store keys in a format that isn't compatible
+ * with GnuPG, see bug 1713621 for an example where this happened.
+ *
+ * This function modifies the input key to make it compatible.
+ *
+ * If this function decides that a modification is necessary,
+ * it will remove encryption (protection) from the key.
+ *
+ * The caller must ensure to protect the returned key.
+ *
+ * At the time of writing this function, the only existing caller
+ * always applies protection after calling this function.
+ */
+ ensureECCSubkeyIsGnuPGCompatible(tempKey, pw) {
+ let algo = new ctypes.char.ptr();
+ if (RNPLib.rnp_key_get_alg(tempKey, algo.address())) {
+ throw new Error("rnp_key_get_alg failed");
+ }
+ let algoStr = algo.readString();
+ RNPLib.rnp_buffer_destroy(algo);
+
+ if (algoStr.toLowerCase() != "ecdh") {
+ return;
+ }
+
+ let curve = new ctypes.char.ptr();
+ if (RNPLib.rnp_key_get_curve(tempKey, curve.address())) {
+ throw new Error("rnp_key_get_curve failed");
+ }
+ let curveStr = curve.readString();
+ RNPLib.rnp_buffer_destroy(curve);
+
+ if (curveStr.toLowerCase() != "curve25519") {
+ return;
+ }
+
+ let tweak_status = new ctypes.bool();
+ let rc = RNPLib.rnp_key_25519_bits_tweaked(tempKey, tweak_status.address());
+ if (rc) {
+ throw new Error("rnp_key_25519_bits_tweaked failed: " + rc);
+ }
+
+ // If it's not tweaked yet, then tweak to make it compatible.
+ if (!tweak_status.value) {
+ rc = RNPLib.rnp_key_unprotect(tempKey, pw);
+ if (rc) {
+ throw new Error("rnp_key_unprotect failed: " + rc);
+ }
+
+ rc = RNPLib.rnp_key_25519_bits_tweak(tempKey);
+ if (rc) {
+ throw new Error("rnp_key_25519_bits_tweak failed: " + rc);
+ }
+ }
+ },
+
async backupSecretKeys(fprs, backupPassword) {
if (!fprs.length) {
throw new Error("invalid fprs parameter");
@@ -2979,6 +3087,7 @@
}
try {
+ this.ensureECCSubkeyIsGnuPGCompatible(sub_handle, internalPassword);
if (
RNPLib.rnp_key_protect(
sub_handle,
diff -Nru thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/modules/RNPLib.jsm thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/modules/RNPLib.jsm
--- thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/modules/RNPLib.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/modules/RNPLib.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -1571,6 +1571,14 @@
ctypes.uint32_t.ptr
),
+ rnp_key_valid_till64: librnp.declare(
+ "rnp_key_valid_till64",
+ abi,
+ rnp_result_t,
+ rnp_key_handle_t,
+ ctypes.uint64_t.ptr
+ ),
+
rnp_uid_is_valid: librnp.declare(
"rnp_uid_is_valid",
abi,
@@ -1611,6 +1619,29 @@
ctypes.size_t
),
+ rnp_key_25519_bits_tweaked: librnp.declare(
+ "rnp_key_25519_bits_tweaked",
+ abi,
+ rnp_result_t,
+ rnp_key_handle_t,
+ ctypes.bool.ptr
+ ),
+
+ rnp_key_25519_bits_tweak: librnp.declare(
+ "rnp_key_25519_bits_tweak",
+ abi,
+ rnp_result_t,
+ rnp_key_handle_t
+ ),
+
+ rnp_key_get_curve: librnp.declare(
+ "rnp_key_get_curve",
+ abi,
+ rnp_result_t,
+ rnp_key_handle_t,
+ ctypes.char.ptr.ptr
+ ),
+
rnp_result_t,
rnp_ffi_t,
rnp_password_cb_t,
diff -Nru thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.js thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.js
--- thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.js 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.js 2022-04-15 07:49:21.000000000 +0000
@@ -288,10 +288,16 @@
document.getElementById("importFromClipbrd").disabled = !enigGetClipboard();
- for (let item of document.querySelectorAll(".requires-key-selection")) {
+ for (let item of document.querySelectorAll(
+ ".requires-single-key-selection"
+ )) {
item.disabled = keyList.length != 1;
}
+ for (let item of document.querySelectorAll(".requires-key-selection")) {
+ item.disabled = keyList.length == 0;
+ }
+
// Disable the "Generate key" menu item if no mail account is available.
document
.getElementById("genKey")
@@ -1522,8 +1528,11 @@
let keyObj = gKeyList[keyNum];
let uidAdded = 0;
- for (let i = 1; i < keyObj.userIds.length; i++) {
+ for (let i = 0; i < keyObj.userIds.length; i++) {
if (keyObj.userIds[i].type === uidType) {
+ if (keyObj.userIds[i].userId == keyObj.userId) {
+ continue;
+ }
++uidAdded;
this.keyViewList.splice(realRow + uidAdded, 0, {
rowType: uidType,
diff -Nru thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.xhtml thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.xhtml
--- thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.xhtml 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/ui/enigmailKeyManager.xhtml 2022-04-15 07:49:21.000000000 +0000
@@ -138,7 +138,7 @@
@@ -178,25 +178,24 @@
-
+
@@ -209,10 +208,16 @@
-
-
-
+
+
diff -Nru thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/ui/keyDetailsDlg.js thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/ui/keyDetailsDlg.js
--- thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/content/ui/keyDetailsDlg.js 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/content/ui/keyDetailsDlg.js 2022-04-15 07:49:21.000000000 +0000
@@ -286,8 +286,11 @@
}
function createUidData(listNode, keyDetails) {
- for (let i = 1; i < keyDetails.userIds.length; i++) {
+ for (let i = 0; i < keyDetails.userIds.length; i++) {
if (keyDetails.userIds[i].type === "uid") {
+ if (keyDetails.userIds[i].userId == keyDetails.userId) {
+ continue;
+ }
let item = listNode.appendItem(keyDetails.userIds[i].userId);
item.setAttribute("label", keyDetails.userIds[i].userId);
if ("dre".search(keyDetails.userIds[i].keyTrust) >= 0) {
@@ -540,7 +543,7 @@
},
};
-function createSubkeyItem(subkey) {
+function createSubkeyItem(mainKeyIsSecret, subkey) {
// Get expiry state of this subkey
let expire;
if (subkey.keyTrust === "r") {
@@ -552,7 +555,8 @@
}
let subkeyType = "";
- if (subkey.secretAvailable && !subkey.secretMaterial) {
+
+ if (mainKeyIsSecret && (!subkey.secretAvailable || !subkey.secretMaterial)) {
subkeyType = "(!) ";
}
if (subkey.type === "pub") {
@@ -617,10 +621,12 @@
function SubkeyListView(keyObj) {
this.subkeys = [];
this.rowCount = keyObj.subKeys.length + 1;
- this.subkeys.push(createSubkeyItem(keyObj));
+ this.subkeys.push(createSubkeyItem(keyObj.secretAvailable, keyObj));
for (let i = 0; i < keyObj.subKeys.length; i++) {
- this.subkeys.push(createSubkeyItem(keyObj.subKeys[i]));
+ this.subkeys.push(
+ createSubkeyItem(keyObj.secretAvailable, keyObj.subKeys[i])
+ );
}
}
diff -Nru thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js
--- thunderbird-91.7.0+build2/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js 2022-04-15 07:49:21.000000000 +0000
@@ -224,3 +224,55 @@
"should obtain key ID of encryption subkey"
);
});
+
+add_task(async function testSecretForPreferredSignSubkeyIsMissing() {
+ let secBlock = await IOUtils.readUTF8(
+ do_get_file(
+ `${keyDir}/secret-for-preferred-sign-subkey-is-missing--a-without-second-sub--sec.asc`
+ ).path
+ );
+
+ let cancelPassword = function(win, keyId, resultFlags) {
+ resultFlags.canceled = true;
+ return "";
+ };
+
+ let importResult = await RNP.importKeyBlockImpl(
+ null,
+ cancelPassword,
+ secBlock,
+ false,
+ true
+ );
+
+ Assert.ok(importResult.exitCode == 0);
+
+ let pubBlock = await IOUtils.readUTF8(
+ do_get_file(
+ `${keyDir}/secret-for-preferred-sign-subkey-is-missing--b-with-second-sub--pub.asc`
+ ).path
+ );
+
+ importResult = await RNP.importKeyBlockImpl(
+ null,
+ cancelPassword,
+ pubBlock,
+ true,
+ false
+ );
+
+ Assert.ok(importResult.exitCode == 0);
+
+ let primaryKey = await RNP.findKeyByEmail(
+ "",
+ false
+ );
+
+ let signSubKey = RNP.getSuitableSubkey(primaryKey, "sign");
+ let keyId = RNP.getKeyIDFromHandle(signSubKey);
+ Assert.equal(
+ keyId,
+ "625D4819F02EE727",
+ "should obtain key ID of older, non-preferred subkey that has the secret key available"
+ );
+});
diff -Nru thunderbird-91.7.0+build2/comm/mail/locales/en-US/messenger/messengercompose/messengercompose.ftl thunderbird-91.8.1+build1/comm/mail/locales/en-US/messenger/messengercompose/messengercompose.ftl
--- thunderbird-91.7.0+build2/comm/mail/locales/en-US/messenger/messengercompose/messengercompose.ftl 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/locales/en-US/messenger/messengercompose/messengercompose.ftl 2022-04-15 07:49:21.000000000 +0000
@@ -84,7 +84,7 @@
.acceltext = { ctrl-cmd-shift-pretty-prefix }{ trigger-attachment-picker-key }
# $count (Number) - the number of attachments in the attachment bucket
-attachment-bucket-count = { $count ->
+attachment-bucket-count-value = { $count ->
[1] { $count } Attachment
*[other] { $count } Attachments
}
diff -Nru thunderbird-91.7.0+build2/comm/mail/locales/l10n-changesets.json thunderbird-91.8.1+build1/comm/mail/locales/l10n-changesets.json
--- thunderbird-91.7.0+build2/comm/mail/locales/l10n-changesets.json 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/locales/l10n-changesets.json 2022-04-15 07:49:21.000000000 +0000
@@ -8,7 +8,7 @@
"win32",
"win64"
],
- "revision": "162654a20c86192e124df9766ec5ecd54143d085"
+ "revision": "2301434270b060c96b796a84843414f71c1539e3"
},
"ar": {
"pin": false,
@@ -19,7 +19,7 @@
"win32",
"win64"
],
- "revision": "3be417e9326ebc9e369fc77f1fd98481a39b07cf"
+ "revision": "a750da883acff8542222b7db4beaacced984d326"
},
"ast": {
"pin": false,
@@ -30,7 +30,7 @@
"win32",
"win64"
],
- "revision": "41dcea23a9d890ee00cb4cc3797559fe461244bc"
+ "revision": "ecdc8e82db16f6bc84e5184d67fec27e9db5ae8a"
},
"be": {
"pin": false,
@@ -41,7 +41,7 @@
"win32",
"win64"
],
- "revision": "d8cbc47ea02faca8963bf8f62df82086c294ff22"
+ "revision": "891f44dca501f396bbf4ba836abf18742420601f"
},
"bg": {
"pin": false,
@@ -52,7 +52,7 @@
"win32",
"win64"
],
- "revision": "19ee7b31e0becafa054013a3c8c09844638f244c"
+ "revision": "9de7fdc78bae439f15788d7a777c83b0de4d5872"
},
"br": {
"pin": false,
@@ -63,7 +63,7 @@
"win32",
"win64"
],
- "revision": "a9e3b8ba10759c8a4f7da6b7970911ded7d04ad6"
+ "revision": "d5ecbe84bbe46b6372e5da06fcd02b7b8e872f8e"
},
"ca": {
"pin": false,
@@ -74,7 +74,7 @@
"win32",
"win64"
],
- "revision": "caf5515093962f3f92c92aea68dacd4c3e520a8d"
+ "revision": "c2c32a823171f88691555d9ad522227f79d9ad9c"
},
"cak": {
"pin": false,
@@ -85,7 +85,7 @@
"win32",
"win64"
],
- "revision": "0bbd8b94c9c02fa5ec6a3e5fd3bf3e69b0432829"
+ "revision": "1251a704bb80ccf0c0bb18bd3d5a7047639e5d07"
},
"cs": {
"pin": false,
@@ -96,7 +96,7 @@
"win32",
"win64"
],
- "revision": "ae677a6bee277f507e673c3fcd2d56088b2caafb"
+ "revision": "18580ca702ca9b40257aa0d9b711b47718552d7b"
},
"cy": {
"pin": false,
@@ -107,7 +107,7 @@
"win32",
"win64"
],
- "revision": "5fff82812b9817b2f616a1e6e134e528c2a24c9d"
+ "revision": "8a8b0bab6bec9178c672199b548c2bb5133f9d3c"
},
"da": {
"pin": false,
@@ -118,7 +118,7 @@
"win32",
"win64"
],
- "revision": "4595dd6f7ed91af507076eb0a95a44f4d0646404"
+ "revision": "edf15c1eaf23bb791ec54de5b68dbda766c4b622"
},
"de": {
"pin": false,
@@ -129,7 +129,7 @@
"win32",
"win64"
],
- "revision": "d3fca46cd495000d26fd26d3a2776b8f4dae786c"
+ "revision": "e480a5cc963f95fb72810b525140c63661929101"
},
"dsb": {
"pin": false,
@@ -140,7 +140,7 @@
"win32",
"win64"
],
- "revision": "611248df8f629860d012cbc8f3a36acfd8744b46"
+ "revision": "53cc18a5c81992a65e435e8ee3b976cf4051c1f1"
},
"el": {
"pin": false,
@@ -151,7 +151,7 @@
"win32",
"win64"
],
- "revision": "fb7a8113c5b26216bde957c4a63ff0e1a32dafa7"
+ "revision": "9a427722011a064b9148d5db31cece3148568c16"
},
"en-CA": {
"pin": false,
@@ -162,7 +162,7 @@
"win32",
"win64"
],
- "revision": "501d80026e4fdeac79e20b41cb8087c7ec3c3ba2"
+ "revision": "2b8cac4abc75ebecf6f31bd40364638cd6fac62b"
},
"en-GB": {
"pin": false,
@@ -173,7 +173,7 @@
"win32",
"win64"
],
- "revision": "ec99571b02068fd4bf160416b5b7e35379c899a2"
+ "revision": "428e1109220e34baf1dee5c8e3398dac9a664a5a"
},
"es-AR": {
"pin": false,
@@ -184,7 +184,7 @@
"win32",
"win64"
],
- "revision": "d190464e290f1cfc89a7ca26cadbd523d0c89e6c"
+ "revision": "2a1f6589c551823a2a81c9440e53ce1db788bdc3"
},
"es-ES": {
"pin": false,
@@ -195,7 +195,7 @@
"win32",
"win64"
],
- "revision": "46729ef124e5cf1f0a3e85d50c16a069602cfed2"
+ "revision": "184451ad84e4d1c83b1316673b12623ff6f42561"
},
"et": {
"pin": false,
@@ -206,7 +206,7 @@
"win32",
"win64"
],
- "revision": "b7a8b9f6c9965756a7a3127fcc1b21375449f1ad"
+ "revision": "0484a0ca8c2361739ecb53997453f64a255771f6"
},
"eu": {
"pin": false,
@@ -217,7 +217,7 @@
"win32",
"win64"
],
- "revision": "863a0a1a315b55c18694e29430c272baba355b4c"
+ "revision": "853864647f080a3134ecc293b3f6fe5561088cb5"
},
"fi": {
"pin": false,
@@ -228,7 +228,7 @@
"win32",
"win64"
],
- "revision": "6e37410128f2d675c3414ba9c6341af81b4521ff"
+ "revision": "17521863b0bb9290b62eae9fd7a60840dae3df24"
},
"fr": {
"pin": false,
@@ -239,7 +239,7 @@
"win32",
"win64"
],
- "revision": "ce1d665cec91d4d29160860dba2350f22f2f4df7"
+ "revision": "b487c59d8a04c5a03b42b9c6a874650963e15a87"
},
"fy-NL": {
"pin": false,
@@ -250,7 +250,7 @@
"win32",
"win64"
],
- "revision": "e488deb4c709d26af77adbcbd922058bbb28d456"
+ "revision": "1320cdf1fb450ea692f58d211bc5f79c4396f3e4"
},
"ga-IE": {
"pin": false,
@@ -261,7 +261,7 @@
"win32",
"win64"
],
- "revision": "2d955174d7ab6068656b2f02e4d8c689bb2399bf"
+ "revision": "e3bb3a295b7ba924bfdd725eefd3e9de43e2a396"
},
"gd": {
"pin": false,
@@ -272,7 +272,7 @@
"win32",
"win64"
],
- "revision": "49032dc335b8b5e9ecd10435f878598bffa6541a"
+ "revision": "39b62325a674ed227e2bdea12ad67491dc3a0f51"
},
"gl": {
"pin": false,
@@ -283,7 +283,7 @@
"win32",
"win64"
],
- "revision": "d8761e8f84efac80d6a7482931a01cecd66dd60d"
+ "revision": "9e100a5adeeac43eaf16fa13c976bee29e1f5dea"
},
"he": {
"pin": false,
@@ -294,7 +294,7 @@
"win32",
"win64"
],
- "revision": "3385ae23e3b569ba9c0c1aca4df25277b81a108e"
+ "revision": "4c851305adea679c3b54f28c696dbe8f147a65f6"
},
"hr": {
"pin": false,
@@ -305,7 +305,7 @@
"win32",
"win64"
],
- "revision": "a01b7ce3515d0b2f05e473625148f11a264da0a2"
+ "revision": "de15ddccd573c9f26818fb4b04769eff085b5c9b"
},
"hsb": {
"pin": false,
@@ -316,7 +316,7 @@
"win32",
"win64"
],
- "revision": "f137d0e6746dc23beff4745474df87c33fae353b"
+ "revision": "e786baca552a4fcc22dfc2e9dc288254733b766a"
},
"hu": {
"pin": false,
@@ -327,7 +327,7 @@
"win32",
"win64"
],
- "revision": "39e18e316a85b5aaada8c560d51317b5e28b77d8"
+ "revision": "b642ef82d64a019a9ad87c9921d184b001aaecdb"
},
"hy-AM": {
"pin": false,
@@ -338,7 +338,7 @@
"win32",
"win64"
],
- "revision": "41e938f8ebf1581d1bc76bd088fc1ac43bb83e0b"
+ "revision": "ed25a859be4d235645dee61830812b93d34ffe94"
},
"id": {
"pin": false,
@@ -349,7 +349,7 @@
"win32",
"win64"
],
- "revision": "4d4de9751872149e1c99dcfce2b7ce4835b65589"
+ "revision": "df459c5785231b35390b635d9f0a8486496d45e8"
},
"is": {
"pin": false,
@@ -360,7 +360,7 @@
"win32",
"win64"
],
- "revision": "d7a3076075faa159db53da86719dabb4a75e75eb"
+ "revision": "8623be99f76ba78853d069a7bae70945423271ce"
},
"it": {
"pin": false,
@@ -371,7 +371,7 @@
"win32",
"win64"
],
- "revision": "3448943cfadfc5a361bd367c7e6be58f86cc61a1"
+ "revision": "f5032961c31b0410328957d45568fd910bfca113"
},
"ja": {
"pin": false,
@@ -381,14 +381,14 @@
"win32",
"win64"
],
- "revision": "c4be75596e316966ab1dc9857a9be6b0a7bc2ef9"
+ "revision": "004f1baf082802d86a609dcb312538a19c33033b"
},
"ja-JP-mac": {
"pin": false,
"platforms": [
"macosx64"
],
- "revision": "476eca379b8b21857655d6c23908b3e2a1b09aee"
+ "revision": "be1ff154a4b4a7e5eac1ecdec92ca292fd1afe5c"
},
"ka": {
"pin": false,
@@ -399,7 +399,7 @@
"win32",
"win64"
],
- "revision": "2d66f0c2bd7a06ac1ad6ad02a09a26ff1e60e3cb"
+ "revision": "81337947d776d2fed44bb804415cb3e84e38bd30"
},
"kab": {
"pin": false,
@@ -410,7 +410,7 @@
"win32",
"win64"
],
- "revision": "409893635bedbe52fa8b85784844e15756d4a8fd"
+ "revision": "2a21776caf4c44fc8fc0e7d7b2330c02da38dd86"
},
"kk": {
"pin": false,
@@ -421,7 +421,7 @@
"win32",
"win64"
],
- "revision": "c68316baa4a0dd041abb4e8efd557339fb0d9cb4"
+ "revision": "51a219b2c24298b520ea028699adf87edc783385"
},
"ko": {
"pin": false,
@@ -432,7 +432,7 @@
"win32",
"win64"
],
- "revision": "88096d30e35f344fcb61f08900340b31fca79cc7"
+ "revision": "1ce43f4e7d36e54e34ee0297667f7febdf861faf"
},
"lt": {
"pin": false,
@@ -443,7 +443,7 @@
"win32",
"win64"
],
- "revision": "6a447408fe67e37ee56a85d8bea523219dac52e1"
+ "revision": "32f2256b09716d2e85f72b47964a6350bb86f870"
},
"lv": {
"pin": false,
@@ -454,7 +454,7 @@
"win32",
"win64"
],
- "revision": "0059bd3f14ced8ec1ef0f2765b655fe4ee537e91"
+ "revision": "bd7d759b7f84fe6b003c1f7a898ad93b04b86eef"
},
"ms": {
"pin": false,
@@ -465,7 +465,7 @@
"win32",
"win64"
],
- "revision": "ec4c315ae032575bed799d8faa57dd4441e5bd9e"
+ "revision": "fea340feae8901443fb3a5217df25c89419c451f"
},
"nb-NO": {
"pin": false,
@@ -476,7 +476,7 @@
"win32",
"win64"
],
- "revision": "490c2d401359fd2204ad7aa806a73107f3befc27"
+ "revision": "4b405501b8d11e73e395b21958cf28f011c2cc01"
},
"nl": {
"pin": false,
@@ -487,7 +487,7 @@
"win32",
"win64"
],
- "revision": "3f55dcbe90edd21965795b84a1601229a36fd4d1"
+ "revision": "098cfe035eb91d43a4e156d341f8b209057acb49"
},
"nn-NO": {
"pin": false,
@@ -498,7 +498,7 @@
"win32",
"win64"
],
- "revision": "6a1a6bca02e894a9e989bdc33813025ecd5acd20"
+ "revision": "54dd71db250efe1ce1e839b954ec3def1b445705"
},
"pa-IN": {
"pin": false,
@@ -509,7 +509,7 @@
"win32",
"win64"
],
- "revision": "b28bb037d4687370eebb7a892982b31bddea32b0"
+ "revision": "3d4b229a30cd2c7a864cc2537fc090062c520ad5"
},
"pl": {
"pin": false,
@@ -520,7 +520,7 @@
"win32",
"win64"
],
- "revision": "3193b4b820e7c37bdb9153ab9c525f18210a501a"
+ "revision": "e22eec04250ce00cdfa8abf61fc4652a8d1a4cae"
},
"pt-BR": {
"pin": false,
@@ -531,7 +531,7 @@
"win32",
"win64"
],
- "revision": "ce1ab16cc1acd0fa7ae898feeba46c6d497fe981"
+ "revision": "55f159519451642392bd00e90ca39b6701bfe069"
},
"pt-PT": {
"pin": false,
@@ -542,7 +542,7 @@
"win32",
"win64"
],
- "revision": "e0910097929ee117291ede6675c6e0add124221b"
+ "revision": "e27715b7ff83861241314aac559e6095ae3cef33"
},
"rm": {
"pin": false,
@@ -553,7 +553,7 @@
"win32",
"win64"
],
- "revision": "cdce5683cd6621c0ca31eb6b6ffd209481fa3c85"
+ "revision": "716264f686e48a005284946e48916254b4d7738a"
},
"ro": {
"pin": false,
@@ -564,7 +564,7 @@
"win32",
"win64"
],
- "revision": "ba7fe96d6c98e01a48f442d520c39d119c7e0727"
+ "revision": "c104292fc7dabaa5001db8ae1b0628314b3ad9af"
},
"ru": {
"pin": false,
@@ -575,7 +575,7 @@
"win32",
"win64"
],
- "revision": "dc6d46ab977eb359c21a0f6dfe5b22e1fa60fda0"
+ "revision": "19e188f9318b9beb6a0a2a432776866ae54b41e6"
},
"sk": {
"pin": false,
@@ -586,7 +586,7 @@
"win32",
"win64"
],
- "revision": "588464d4ecd69c9a12ffd0e41ccb5e4a7f16e25e"
+ "revision": "8f6e8065a1a7f575d8f3cc742831dd2ffd0343d6"
},
"sl": {
"pin": false,
@@ -597,7 +597,7 @@
"win32",
"win64"
],
- "revision": "d5882d14036a97883f3aedbaa93e0d01720e0c8f"
+ "revision": "b5c6405a8fb26d32acb46f7d6717c49934fb05a6"
},
"sq": {
"pin": false,
@@ -608,7 +608,7 @@
"win32",
"win64"
],
- "revision": "05efafdd60c5a69d6d75adf8ccb97c5b07aee239"
+ "revision": "5b81bb3f636b3ba94b5b4ad6bf658322751ce133"
},
"sr": {
"pin": false,
@@ -619,7 +619,7 @@
"win32",
"win64"
],
- "revision": "e7c7978d2fd74f4e2098253a41b099604b88d61b"
+ "revision": "0deba25cdae68c4f1510174614f1eb76a390274e"
},
"sv-SE": {
"pin": false,
@@ -630,7 +630,7 @@
"win32",
"win64"
],
- "revision": "30479c6d22a77f896ea16e6266392711ea79a854"
+ "revision": "71e47714e048f96da8d333be759a4d5889e4e55d"
},
"th": {
"pin": false,
@@ -641,7 +641,7 @@
"win32",
"win64"
],
- "revision": "b6c8c65ece954839a983d48aa92a348b84867fa7"
+ "revision": "8bfbdb39ef3d3d041db98ad672b555a617575e6e"
},
"tr": {
"pin": false,
@@ -652,7 +652,7 @@
"win32",
"win64"
],
- "revision": "810f0ebde4235bf764070b3f0628cfd712446aa3"
+ "revision": "a2bfbc116e8e57837395e09d8f8e0a96b8b837c6"
},
"uk": {
"pin": false,
@@ -663,7 +663,7 @@
"win32",
"win64"
],
- "revision": "51ac98096a376ade0e29ba477d20e86e8e553eaa"
+ "revision": "1d987f6fa4abacd5db2018990756309a30df0f4d"
},
"uz": {
"pin": false,
@@ -674,7 +674,7 @@
"win32",
"win64"
],
- "revision": "f8e8cc127eaf07ab77bf51c37ec494d2721e8d2e"
+ "revision": "f2b59b0a2d0b7fbb91b2fcb519db4db8b2e70d9a"
},
"vi": {
"pin": false,
@@ -685,7 +685,7 @@
"win32",
"win64"
],
- "revision": "e24285029832c0cc588e8e12aa2212dff982d623"
+ "revision": "3c9cce6136a1876644b6465be037c1f8da08d385"
},
"zh-CN": {
"pin": false,
@@ -696,7 +696,7 @@
"win32",
"win64"
],
- "revision": "12b859d962f2252d012eb9ce4e8c3a8e1b31c68d"
+ "revision": "59dfbde33841356637a31ec79ff2796df732a889"
},
"zh-TW": {
"pin": false,
@@ -707,6 +707,6 @@
"win32",
"win64"
],
- "revision": "74f0fae3d31431cf742b41a2832a0e8b3bdabce9"
+ "revision": "d6a70a4a85be1ea53a167f6891f494645d6f86e6"
}
}
\ No newline at end of file
diff -Nru thunderbird-91.7.0+build2/comm/mail/modules/MailMigrator.jsm thunderbird-91.8.1+build1/comm/mail/modules/MailMigrator.jsm
--- thunderbird-91.7.0+build2/comm/mail/modules/MailMigrator.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/modules/MailMigrator.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -127,7 +127,7 @@
_migrateUI() {
// The code for this was ported from
// mozilla/browser/components/nsBrowserGlue.js
- const UI_VERSION = 30;
+ const UI_VERSION = 32;
const MESSENGER_DOCURL = "chrome://messenger/content/messenger.xhtml";
const MESSENGERCOMPOSE_DOCURL =
"chrome://messenger/content/messengercompose/messengercompose.xhtml";
@@ -613,6 +613,12 @@
Services.prefs.clearUserPref("ui.systemUsesDarkTheme");
}
+ if (currentUIVersion < 32) {
+ this._migrateIncomingToOAuth2("imap.gmail.com");
+ this._migrateIncomingToOAuth2("pop.gmail.com");
+ this._migrateSMTPToOAuth2("smtp.gmail.com");
+ }
+
// Update the migration version.
Services.prefs.setIntPref(UI_VERSION_PREF, UI_VERSION);
} catch (e) {
diff -Nru thunderbird-91.7.0+build2/comm/mail/test/browser/openpgp/data/keys/secret-for-preferred-sign-subkey-is-missing--a-without-second-sub--sec.asc thunderbird-91.8.1+build1/comm/mail/test/browser/openpgp/data/keys/secret-for-preferred-sign-subkey-is-missing--a-without-second-sub--sec.asc
--- thunderbird-91.7.0+build2/comm/mail/test/browser/openpgp/data/keys/secret-for-preferred-sign-subkey-is-missing--a-without-second-sub--sec.asc 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/test/browser/openpgp/data/keys/secret-for-preferred-sign-subkey-is-missing--a-without-second-sub--sec.asc 2022-04-15 07:49:21.000000000 +0000
@@ -0,0 +1,129 @@
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+lQVYBFLtfH4BDAC9ad3c2rD5jOZ0ynonf90JzXHvPeoksmj7fMT2KX3FTg+lzdKG
+40Pxk3/53/otqvYOvw8A6Pb18fOLlTvkTMQ2CFjRqd4oydFKHZjM+gWBoyFWMq2X
+PRIrYw6n3LJb6/wfula4rgnCVE4gOSkTBtto0yJCZtHQMh2blBtq2W/jNJs+OEpf
++LLDoOhO7B31HdWiVHuQTMG7sZwrH6MwuZKU0tYuwoA/Eeznuy9X42IKc7WEA3fj
+0A7Eme8Bw8lnZ1kiLe6jgAA1DxKBbu2dB3ParC+d97FZ6pWwnd0JiWZ7ws5F+KBF
+r4RSnJ552xUjrmiFehbAIZ1I9EY9m7eQ62lhOZAa/WfE7WA7hyufgpf0e8CR01Tj
+60ckFrfoTXnumWOASDJLUaGaGo9J2yjbBjcut8Nn2OfXysofzVevkrCi/zLFHWPa
+mjoa+M2R7vBl5alk6XoLSN0SBzDLeXpMdVfNBqLrlC4QbqI2oakkqEpX2VEV3f9Z
+ozlizzNMYSWp50UAEQEAAQAL/RwJ/29RqlAOxRC15nZRbcGlOX/+bNpI1NShqDB+
+fOFHyHY1bTxNiUHKIXA2cTzwaWNOciSi1+gZjIF1snt9x6/t9WP4Huxvz70Ge5eg
+TU9e/DDb6KmSP03P6Jv9xiNoYBa8SVkmXkh3nWcUvxlTcwhl9NTajqWgvZRJzPM4
+w+Dg6ThBMfVaBfCCsdD5EAg4heb1VaNLUYR86s7RbKFqXyILwewDG+P6PdUh9wSu
+ItXEQjMMJmPBaWY+GUzsFDTr7dsvFCRD2rJhaTlFaJhfN2F5dSrBwGQvNlDueity
+DbGBvYU6KzOuHwo37/dpRQ7NdQk9OGN0foLE7t5MxiCVpnzdtTXO0ypbPU9xSpkP
+Zo7c2ufPGx2HFVUW/9GKCruxR/aLfXCzkYC1ZbO26tjjp4YA0lQMOtCormjMFiw4
+OR3rISCvAuQ106nvjyfBs6UmtYJExaFdzERZqw8+Z/cT5lNpptHxtRQIN1eLktMv
+d8tWiDAHCurRqbthAJ/FQAs5gwYA1L32mx0YpfRA6S9DNAElR+s+ffkcr3I7dj5A
+RsAlsT0OXqFFfA007kB1+13Aww2UFnDI2gVkEWsFa75YUY9iUKOjllFyT6HFJiyq
+NzTv1V96OJOzrgfIzBdttZhb1YdlG7qnHQt7u8jeBCjVaB+7wzRCk0dknG/i9Qqz
+y4huWbu1KOlRE4FsrqguYR6e/O2KVBdvAkqlp9KcIWUoXyA7p3bYnQgqV6qGUHgM
+YZh010rMXpmtqKSIyjr4PekuPhI7BgDj7ZDLjLeAOCH3fdNKYV02oBlEpio4P5RR
+EoShoyiocczBXUfRolgJyO+8+4eKjs+xJNYiQDeZr8MrMkodXWXZT75uiBKBmDEN
+jaTMFp9C8nubmZ0ai7f4R8d49+XHy77h2yMTiwcNs2iLfSPWXl0VS8pFS4XfobMG
+ixhOG6p5Y2Rjc/t4uEDV+n11em3BGD5+d4/8WvBw+b0UVIrHnWbKCWDmE9FvB/fc
+HG9lDExvwJn++COsyK+lG2NlZJby1H8F/21hYNQGeFIBNSeDrPxRC4tgHHOA1LH0
+9qgEek6Zq9Ag3zblY4r3c5AnV4dMu7lnzseFUnBpb73SxsRD7e+6rg59wpmDeMs4
+ajpM9YLmVdPgYmn6OjpxdfmKgYpMZTjisGGFm7XbKKQ0GEFuo3oQggZYMuQ+d3eK
+cC+89gMU0eyP0gRg75feJpxlM158B6uVYB8pfap2d2yfeadJPcBSSdoVuwl2zQTK
+ECP46uW++mhN2gBVU4iyMphyrclOPbe8ItgBtDdzZWNyZXQtZm9yLXByZWZlcnJl
+ZC1zaWduLXN1YmtleS1pcy1taXNzaW5nQGV4YW1wbGUuY29tiQHOBBMBCgA4FiEE
+cagS43SiqCdNHP5mW1w0QlGl2n4FAlLtfH4CGwMFCwkIBwIGFQoJCAsCBBYCAwEC
+HgECF4AACgkQW1w0QlGl2n7aywwAgWr9bhgNwzesG7pJo2G0v5E/XlznEInkSxCl
+xTuRLg6uzQnLnFB4dCkN4TNhfrVkPl+PZS7BM9D84VwIjO7KbSnDILXt/eOi1uYk
+EdDLKrTxc7OAQMmnktvw3t8xsul+HvjY5EEYMz73+TWS5DHPuOX8B3gtzOnTDMfn
+PrslkmakypoQe+CAsjh6JZoHt19RIlvVg8xr8Gx0SeXlp0ZO+SA52Wb/Tp1sTpXV
+H8QBf5iOj++9wxaf6kJvRvdZqtxgqBSTaq3/w1z4Achav5/fofiQgQaJ2A02r4Uj
+RleUfMjF0RiFbu7XS7XXBvQ8Qnt00J0I91v0WnaagheDEyRezOoKYXh7ArU9X2b6
+uxumXDB1eSoR8HUMDxsEtmBEVxoXH8DhqDkiYXzrfm9GKdrIAzz/Miwxqb9G2XGq
+oX2VRBkpnGoaNG6K6a2v3kvfSZFKXCjfiRDVNeK6XL7f/VOqcO/gX+6UJHlqytNf
+ONloSdzOzWmgP9MH0vZxbeqEppVOnQVYBFLtfH4BDAC2k4vdz3B1pZfwC0jzWeZC
+uFLxZEBHKBJlt6q19PGovRZz3IXZE/pHNAsfSYZn82eJa9OJ9+BIUSjkxzA4Drnf
+Vg5mLk+bmy/LcH2IBVxZTBSiSjWkZijBqLjPDL+DKOp04LUYEoRFdmvC8pzDYdy3
+Fei32TBlie/VLIOHJY0YHjziYscIu6OhTnRsx2AcAeCxPr8BWxWWpLzoK1Bg3Ka3
+TnI9AqzqEFs0QChVuti7gzz2ItGhE6GUP6LyHVQJYRZgCyGzCxw2ObM3lsRBIpLU
+i0S0bcwfnaI8ZEJtRJp0ogdJvgzdnPa4AS93otmAsy0EeypKtW32yDH+bz9ddk4S
+if7Mat20m5dNNxFGecCGKUnk8JooiFg/5NmBOkCOuKV+foNSkbf+Ue++Yg3KVW5J
+ewpTJzgBENHKJKDYhUCnTJ4R38Yb/8Ub7caXibWJ4t/cQ06mymnm61rthQ57adz3
+ChC0+r+q1zj/eKI+rPyMWcRRUFWpZBBVds1Woje23jEAEQEAAQAL+wSYboJ/73gl
+ma89AHpAFLawlCVfaSsFVh+1bZSAgKHnNwDF7+BGs4Ot6psALzPv/WbZBgE8sgpt
+8Qgfn54EmF73x/tgTmiHsZ52s5EsNd6pRqJuWN7tQ5i6xAKRowMkkTCtjH9ZbXcA
+X95ffAzCqoMY+ANjIgfHPtg0M3AQFNbi4XRPCUyV6PylGHL5unh//1lkv3rjsZWZ
+6keTegWjHibiYIeauPKYBGyqcf1061I+b5cQKau6zlQIfUPn8zLcfMBd0d09QOAM
+JU5nPEMtWZKbow67eaCN66k23vI9bNbKMV+1et85gYa6dlgPYqcVTCNrNrcrRnlB
+eXbOTWVqVPkuDZWpYrC9dYVxF7CQvSOHOCVwZNojirMCJTYhCwsvL7GOp7UPIfiP
+2OOWclBBCpNsYDRxqTqp8KarlZPxl/bZkkcYDX6zWLN84ArAfUsGJsYHUiOQInUi
+UKG7R+GLsmmzLux1yBpkaQI8vJU9TBUZUrbu5cE227UzwkLlg5Ul4QYA0/iGHn6x
+fQh3u/fhdHkr1Noc7WbbPQopkdfAtOTZF16b6PG/JGRjgp01/bjCm7pc27JwjOuW
+e09SgNJ1zXfFvRa0XgOC7ZX22CAxT0nT/OUYtMa4cg2HndvDikOTOjDwKGjMzvuQ
+Yd5O4/NxkYVwdEEBy/MDsT2hUMgHXa22JGRGveTWZS2Pk1eWsoJPTcxDttE8a/Na
+jtqzNpGh6YZe0FyvcQmi7UIIeTm/1Rv4qc15DgaLms51fEzUtLJEIT5hBgDcf/uW
+PMQRVCxkexQgINUzqx2w2VEUnkgyMSaiTuKhJT90VhKy+9Yb1YGRKGA/SsdWhV7Y
+gxmoT73vbKB68KGIB4RS157jNH5DMlfMXXhuF0QRZm32jU7a4ShP/Do9KsHXCNva
+ZKc/DczrLfpnBjMWwS0w93pNQeZI2M1tHp07BMyW2JiNtcGXbz0iWq6tsq2J6JLY
+KbnW83KGXCvfLBS0N6qhP6i3fUktWZ17P3g8xLdQlCBii6VVdYRUkeD+kdEGAI8w
+K86sWfq+RCKwcNtfEXQZZ8ATOzYDDW0WPodU8suUqXuxEZUw9sG3EquIUSrmCGd9
+fWvAgxfHcE/RPjNn1xT+8soO+CeT84jhCpGcYAiWcOkFuOjYMsBQNSQmuz0GPnJf
+OOF8EWkJNXsp2JVZgCkMhBBnFWXM6CVydqaFQ6jspGt/LKsVBTtAxUisrjFB/f1k
+DhRd0zknWVZqrK3n0f3WiKgZpaEt8eclCypEsUywPvjah+HEO6LbziLftEBVkNXX
+iQG2BBgBCgAgFiEEcagS43SiqCdNHP5mW1w0QlGl2n4FAlLtfH4CGwwACgkQW1w0
+QlGl2n5MeQv9G8ZjWnszJAZa7iF0KnJrRInsrpiduzG2iONb45z1G3arXKkD2sKt
+2KL+AgMtLx+/DXHKsoJBNgjXmkM2EYiMUuKTpzsqE9TPNtnu5maZFc+Q0tMK9Ycf
+Ot/zLCja0Owxf0975Zg0Cck9JZSDGUqYTtYWaIQ+gID3bvtb9/5yEQ+5KmtdLYUH
+/yCeXraZ9y8rodHW91cVLCY0v3r3pgaV5zCB5iw1SwVnAWMqcA1s4oHffwOJTVQb
+9OoC+Yq2z4Nk86+wubEqnC+5x76Xqep7jIARRXWeuVufsUcci6YPNWmnHpd8/BPu
++nbvOVVD/X9fhOdxbL0DNymHmbh5zAsNz2l1rm58u8ACxx8UuugukgkKRmIcpxZE
+WRLGn7czwjUfluttSDCDDLMC9cP/R9sJyM+QTD+hK2sNCvx4nrHAf8jiDtk1Y+9h
+NXIvVXzuRp2W9nPJJopuAAGBvPizZF3Ej3nITJddb423z8+Jb1kAUKzH2wXSzgSh
+iPbtdboNhtsinQVYBFT064MBDADPZIdxXmDJJbnSfzgOI8c43YSteEFtJjSmTUo4
+fAMz/4RNk24FmFnnDNTqboE5qFVK7Mf6Zxbmgjo0cQQzPFPJXk9YyuN9Ge5lLeaQ
+0fXyfpIYTPbcunqBrbVjMcnI/v+x6O9ma+5c3AzX1CkRm0YrSu9t55Fm/y3bP/2u
+L1PVSmAr+AZMhMZf3xP7TZQXwqx1aROdUARAk6zR44JyiopOApCA5vwZsMgg/2rV
+t+B9VH430wqkQV53IGINXCum5oMpeBxm+LrzpYnZiUrMLv4uZkmmj/5Mx3+aDfIS
+u7+cmvbNzHoRsIBwphUtGD+SNdFr95wXSjxSfA6NNTJWGD1Gi9l2bO2grVq1j7sz
+h2QconAPrXv4hB72RxPAZP6gV0jfApb22ihEKi5FuOYY0i4halWBGWOXpseQue26
+fM+XsoS83TwMyk7lAA5a4hVQZDUr/JJjdIJkCtqoxixF+AU7W7w/1vnVgAGai8I1
+QI41KiGkm9F9nU/dCtQmnjuLu3kAEQEAAQAL/RSHN9zh4aSnZlBOpWbI5dRcIODm
+0VsTeAyqA9m5dLu15AultzM4lFWJcJ3P2Fyzq9WhwF2pzJt+cnJ0aV0E8Koy+pmo
+Y4IjifRb6cGV9slM+/sJyzmn/65MWnL6H6YUj4y1qNSzhEGOynqmlnYWr4hjf3Wa
+gUr3oTtdhyexqZOoLALOJxl13wjoVNsAH9OGQnnQr89Xd0RJGccgxO2/htcX6+PG
+eVe1pumVPqbu73qYXXH7IseFbOtPukTmRa/cixtv6Dda6FX63k2pfA+xbGTEijx1
+NXsU5Ol7wW1ZrhmJxIPRtTJrRAaPHDJzzx6p6WTEz0d2efe30UCS6aYuWy3yTe56
+TDyMlspHcsyw2Elr+1wthkjrZ1zXgGAP7kQtBmpEwyeSP7Fu49Fw8fSm0D027nbH
+SaqN2R/nkuqclFvUfg2WcskBc/Q51/qr2MTNlYWK+/uP7XKhywrzSlzLHnaxrlL3
+ESY1BZkZ9t9Va5sXzWBR2J8ogCMMv1ta9OSMMQYA3muIQo79ZZAnqLUECrHP0cst
+3PgfCGxED1aAZ68rlO93+pTA0kHlHURXGLVCLM5jP2UpTfN3oymJbjmr9WvZqcQY
+mRvJ9R2SuCH8tb6QZt0pT2nyhHuEwT/TNbtE04wMH2unHhmuavp20MqcFmXudI3b
+YEMa9zd51JPMtjB/UpkfXyXeIjjXnkZvbIuu+Ah93Z9xiKjkczEljX+ynFOLGOf5
+KTqDDDXepzO7YMZhIfhYSVLLX4/d5o6q0YLVllR9BgDutDGrnDn87bYl8hUQb7h6
+AkQeimrgqBuZ2B+Ubqq2f6Y52oKV9RS49KKrc+/DNSbME1+2/39W+NIPOuUB69UO
+48b9bmSiGOdUR02y9LYaE4qLCDR4gVmERsekf+GnaRFx/00gFgXCWnw1e5emcUPR
+W7hfrDzLO4At2vU+kPEbbnvlh64gs+tPz0c5AmdsqwZi000IQsvkzfXMI0LsZVNF
+NsAulu9B9lz1BMJ3pb8Hxf47oHAdxX3R0/OocRBXn60F+wcfplWrStRARMGK+/CM
+voYZKEWRZ6pk44a/vq1L9/VALUiGRB4XvXdiQK+rOH5vVJRhH9LFTgoM00X+sGZf
+r8WBbFl+hBHe5z+SUi916+qLq4+qhz/VwLTRZCZrBgEqxYsu0L4h7jKRL3ifZCV+
+nBf+4ObHXw8gk0+PT+ZuNQ28gslupvayWWcloMxxIT7KPVMvk+D4f4bYzhI0DCGZ
+Jbf4F7KOPMlN/ZYiz8jrFeIWeZjA1y0Sy0e6AKaKj4RJA/JriQNsBBgBCgAgFiEE
+cagS43SiqCdNHP5mW1w0QlGl2n4FAlT064MCGwIBwAkQW1w0QlGl2n7A9CAEGQEK
+AB0WIQRhIYHmBsx+W+KdrGhiXUgZ8C7nJwUCVPTrgwAKCRBiXUgZ8C7nJ0OrC/9S
++9c+9dlCz7ls/Ez8+3fnttL72Ui2VPEgB+KYj71K6Jx/29JFHec2Bl35Si/6NSWx
+25rrEbbYtcXQPqu0W7PqAfzytx+GxCdMDUHqMdcxx8mZn4WCYVYwxOhsNMQIZHmz
+0noJnHholQ9XsGVWkV9TPyW38zGVC0yHAakrJ5ZFuJN4f7UNydYgwyVtPbVfOryd
+7dDPaBNJOPjpgQ2Xuj1p4Ygz0WQZ+FYl8EcV4jzYi085lhuDCjX9gbF5IkIkjLZm
+RKpAX3tR8L+d5x8gTuVTZoLrpSDZR0WsSPFhgKKiY/hVo0oPKXoSz1DOygwk1PMS
+cEiJ5jbGYvQ+yBJbJO02O4fXTeiKYHONBIhu7fl+49JMXqOscHoKsP7PlCZ87YKq
+u6S1h/nHY+vVpbnhV2XDINWpn7d1qsBfewy/plXf5BPB4334ruqclz12DqreHXtO
+IzFr6LSTm4pIWia1Nxu03qXwCl9dhhBQCWZ00bnYzL19sWnN6HLdfvTdYxNPzn5T
+Ugv8C0Boxbf8lhkiy0+P8Z9JKP0sSRhjKlsoi7hk2artsfcPGOcid7WNP3Ruc+rh
+IQADbgjSHnUpJ892XPkJ58yUEPCr0B1+GkV93Lv41Q6UHqDHJOWeWqhOoD/qRT+6
+ZRGGA3BQ2xmxNKphsUx7uBcndQsig0JNCMawH/OklvlBqDMthlOFMeSfhkVvLymy
+DtikFrdkYQmo/IrFHe0leeiQ671ZF6MRxtnx6NmtJo29LOquReTU2LZyUJ6q6XEk
+daH1Av2c1u0BmIJoHSUgHaxM1wJ7oSE9GfGS9dDyWADAKv1obVb3Zpi5Dzr/oBN+
+ipstAEUYvBlLvaitt3Wvx9/8QUTpqxCQJk2owXE8omY2xH/yBJCiF/ht8+cUKw/a
+lbiFAUz9S2ncUC2j1j/myF17obcnrDWKwMbW0BPIkZmIqKyKp4GTL+rEkGiZzqcf
+s5zFIgnbiE4E7r3nKR3uc8RbeJ631che4mZjFi43lt7KVOAC+OD2j+tCnPz04f8H
+iUE5
+=f5S8
+-----END PGP PRIVATE KEY BLOCK-----
diff -Nru thunderbird-91.7.0+build2/comm/mail/test/browser/openpgp/data/keys/secret-for-preferred-sign-subkey-is-missing--b-with-second-sub--pub.asc thunderbird-91.8.1+build1/comm/mail/test/browser/openpgp/data/keys/secret-for-preferred-sign-subkey-is-missing--b-with-second-sub--pub.asc
--- thunderbird-91.7.0+build2/comm/mail/test/browser/openpgp/data/keys/secret-for-preferred-sign-subkey-is-missing--b-with-second-sub--pub.asc 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/test/browser/openpgp/data/keys/secret-for-preferred-sign-subkey-is-missing--b-with-second-sub--pub.asc 2022-04-15 07:49:21.000000000 +0000
@@ -0,0 +1,95 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQGNBFLtfH4BDAC9ad3c2rD5jOZ0ynonf90JzXHvPeoksmj7fMT2KX3FTg+lzdKG
+40Pxk3/53/otqvYOvw8A6Pb18fOLlTvkTMQ2CFjRqd4oydFKHZjM+gWBoyFWMq2X
+PRIrYw6n3LJb6/wfula4rgnCVE4gOSkTBtto0yJCZtHQMh2blBtq2W/jNJs+OEpf
++LLDoOhO7B31HdWiVHuQTMG7sZwrH6MwuZKU0tYuwoA/Eeznuy9X42IKc7WEA3fj
+0A7Eme8Bw8lnZ1kiLe6jgAA1DxKBbu2dB3ParC+d97FZ6pWwnd0JiWZ7ws5F+KBF
+r4RSnJ552xUjrmiFehbAIZ1I9EY9m7eQ62lhOZAa/WfE7WA7hyufgpf0e8CR01Tj
+60ckFrfoTXnumWOASDJLUaGaGo9J2yjbBjcut8Nn2OfXysofzVevkrCi/zLFHWPa
+mjoa+M2R7vBl5alk6XoLSN0SBzDLeXpMdVfNBqLrlC4QbqI2oakkqEpX2VEV3f9Z
+ozlizzNMYSWp50UAEQEAAbQ3c2VjcmV0LWZvci1wcmVmZXJyZWQtc2lnbi1zdWJr
+ZXktaXMtbWlzc2luZ0BleGFtcGxlLmNvbYkBzgQTAQoAOBYhBHGoEuN0oqgnTRz+
+ZltcNEJRpdp+BQJS7Xx+AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEFtc
+NEJRpdp+2ssMAIFq/W4YDcM3rBu6SaNhtL+RP15c5xCJ5EsQpcU7kS4Ors0Jy5xQ
+eHQpDeEzYX61ZD5fj2UuwTPQ/OFcCIzuym0pwyC17f3jotbmJBHQyyq08XOzgEDJ
+p5Lb8N7fMbLpfh742ORBGDM+9/k1kuQxz7jl/Ad4Lczp0wzH5z67JZJmpMqaEHvg
+gLI4eiWaB7dfUSJb1YPMa/BsdEnl5adGTvkgOdlm/06dbE6V1R/EAX+Yjo/vvcMW
+n+pCb0b3WarcYKgUk2qt/8Nc+AHIWr+f36H4kIEGidgNNq+FI0ZXlHzIxdEYhW7u
+10u11wb0PEJ7dNCdCPdb9Fp2moIXgxMkXszqCmF4ewK1PV9m+rsbplwwdXkqEfB1
+DA8bBLZgRFcaFx/A4ag5ImF8635vRinayAM8/zIsMam/RtlxqqF9lUQZKZxqGjRu
+iumtr95L30mRSlwo34kQ1TXiuly+3/1TqnDv4F/ulCR5asrTXzjZaEnczs1poD/T
+B9L2cW3qhKaVTrkBjQRS7Xx+AQwAtpOL3c9wdaWX8AtI81nmQrhS8WRARygSZbeq
+tfTxqL0Wc9yF2RP6RzQLH0mGZ/NniWvTiffgSFEo5McwOA6531YOZi5Pm5svy3B9
+iAVcWUwUoko1pGYowai4zwy/gyjqdOC1GBKERXZrwvKcw2HctxXot9kwZYnv1SyD
+hyWNGB484mLHCLujoU50bMdgHAHgsT6/AVsVlqS86CtQYNymt05yPQKs6hBbNEAo
+VbrYu4M89iLRoROhlD+i8h1UCWEWYAshswscNjmzN5bEQSKS1ItEtG3MH52iPGRC
+bUSadKIHSb4M3Zz2uAEvd6LZgLMtBHsqSrVt9sgx/m8/XXZOEon+zGrdtJuXTTcR
+RnnAhilJ5PCaKIhYP+TZgTpAjrilfn6DUpG3/lHvvmINylVuSXsKUyc4ARDRyiSg
+2IVAp0yeEd/GG//FG+3Gl4m1ieLf3ENOpspp5uta7YUOe2nc9woQtPq/qtc4/3ii
+Pqz8jFnEUVBVqWQQVXbNVqI3tt4xABEBAAGJAbYEGAEKACAWIQRxqBLjdKKoJ00c
+/mZbXDRCUaXafgUCUu18fgIbDAAKCRBbXDRCUaXafkx5C/0bxmNaezMkBlruIXQq
+cmtEieyumJ27MbaI41vjnPUbdqtcqQPawq3Yov4CAy0vH78NccqygkE2CNeaQzYR
+iIxS4pOnOyoT1M822e7mZpkVz5DS0wr1hx863/MsKNrQ7DF/T3vlmDQJyT0llIMZ
+SphO1hZohD6AgPdu+1v3/nIRD7kqa10thQf/IJ5etpn3Lyuh0db3VxUsJjS/evem
+BpXnMIHmLDVLBWcBYypwDWzigd9/A4lNVBv06gL5irbPg2Tzr7C5sSqcL7nHvpep
+6nuMgBFFdZ65W5+xRxyLpg81aacel3z8E+76du85VUP9f1+E53FsvQM3KYeZuHnM
+Cw3PaXWubny7wALHHxS66C6SCQpGYhynFkRZEsaftzPCNR+W621IMIMMswL1w/9H
+2wnIz5BMP6Eraw0K/HiescB/yOIO2TVj72E1ci9VfO5GnZb2c8kmim4AAYG8+LNk
+XcSPechMl11vjbfPz4lvWQBQrMfbBdLOBKGI9u11ug2G2yK5AY0EVPTrgwEMAM9k
+h3FeYMkludJ/OA4jxzjdhK14QW0mNKZNSjh8AzP/hE2TbgWYWecM1OpugTmoVUrs
+x/pnFuaCOjRxBDM8U8leT1jK430Z7mUt5pDR9fJ+khhM9ty6eoGttWMxycj+/7Ho
+72Zr7lzcDNfUKRGbRitK723nkWb/Lds//a4vU9VKYCv4BkyExl/fE/tNlBfCrHVp
+E51QBECTrNHjgnKKik4CkIDm/BmwyCD/atW34H1UfjfTCqRBXncgYg1cK6bmgyl4
+HGb4uvOlidmJSswu/i5mSaaP/kzHf5oN8hK7v5ya9s3MehGwgHCmFS0YP5I10Wv3
+nBdKPFJ8Do01MlYYPUaL2XZs7aCtWrWPuzOHZByicA+te/iEHvZHE8Bk/qBXSN8C
+lvbaKEQqLkW45hjSLiFqVYEZY5emx5C57bp8z5eyhLzdPAzKTuUADlriFVBkNSv8
+kmN0gmQK2qjGLEX4BTtbvD/W+dWAAZqLwjVAjjUqIaSb0X2dT90K1CaeO4u7eQAR
+AQABiQNsBBgBCgAgFiEEcagS43SiqCdNHP5mW1w0QlGl2n4FAlT064MCGwIBwAkQ
+W1w0QlGl2n7A9CAEGQEKAB0WIQRhIYHmBsx+W+KdrGhiXUgZ8C7nJwUCVPTrgwAK
+CRBiXUgZ8C7nJ0OrC/9S+9c+9dlCz7ls/Ez8+3fnttL72Ui2VPEgB+KYj71K6Jx/
+29JFHec2Bl35Si/6NSWx25rrEbbYtcXQPqu0W7PqAfzytx+GxCdMDUHqMdcxx8mZ
+n4WCYVYwxOhsNMQIZHmz0noJnHholQ9XsGVWkV9TPyW38zGVC0yHAakrJ5ZFuJN4
+f7UNydYgwyVtPbVfOryd7dDPaBNJOPjpgQ2Xuj1p4Ygz0WQZ+FYl8EcV4jzYi085
+lhuDCjX9gbF5IkIkjLZmRKpAX3tR8L+d5x8gTuVTZoLrpSDZR0WsSPFhgKKiY/hV
+o0oPKXoSz1DOygwk1PMScEiJ5jbGYvQ+yBJbJO02O4fXTeiKYHONBIhu7fl+49JM
+XqOscHoKsP7PlCZ87YKqu6S1h/nHY+vVpbnhV2XDINWpn7d1qsBfewy/plXf5BPB
+4334ruqclz12DqreHXtOIzFr6LSTm4pIWia1Nxu03qXwCl9dhhBQCWZ00bnYzL19
+sWnN6HLdfvTdYxNPzn5TUgv8C0Boxbf8lhkiy0+P8Z9JKP0sSRhjKlsoi7hk2art
+sfcPGOcid7WNP3Ruc+rhIQADbgjSHnUpJ892XPkJ58yUEPCr0B1+GkV93Lv41Q6U
+HqDHJOWeWqhOoD/qRT+6ZRGGA3BQ2xmxNKphsUx7uBcndQsig0JNCMawH/OklvlB
+qDMthlOFMeSfhkVvLymyDtikFrdkYQmo/IrFHe0leeiQ671ZF6MRxtnx6NmtJo29
+LOquReTU2LZyUJ6q6XEkdaH1Av2c1u0BmIJoHSUgHaxM1wJ7oSE9GfGS9dDyWADA
+Kv1obVb3Zpi5Dzr/oBN+ipstAEUYvBlLvaitt3Wvx9/8QUTpqxCQJk2owXE8omY2
+xH/yBJCiF/ht8+cUKw/albiFAUz9S2ncUC2j1j/myF17obcnrDWKwMbW0BPIkZmI
+qKyKp4GTL+rEkGiZzqcfs5zFIgnbiE4E7r3nKR3uc8RbeJ631che4mZjFi43lt7K
+VOAC+OD2j+tCnPz04f8HiUE5uQGNBFcBkmMBDADxUSvSq2B7ctdtq3EyR/msyv0w
+zqjE/r/2DAZyodM5Rkz4vSpKL4GWs9dfXFz2g+0snmH95uHTbZ1sV7R0jdD9y0nW
++cz6/eAvZmeDD8fkpaz13T1LiptC0Y1jqpmPUN0tMBCx2ILA/gbogV1N4CG8VB2q
+fbbovIF1xUBbw5iT76E77JqrNZ2YxgReaxSfZHjcih0V3k2tshv3CBkFjbwx2WtD
+jJ1ZuRMDxMdJzstwKwq2m67Z8eYzvZuJFeBSg6cyXm1lEqLsZg6qSvSa8NWJb2b8
+0/OTQj+Nc+wDptuvgUVpdCTnuhejahzSNUR6JZsndvSnUsKviypOTSHh/4L678WI
+sNEFuAv0iYEk+AhpMUIXAll/p0G435bOxkOtWFSbkIkLlvpN0pRF6umn0z1D0Bg6
+XUKeqZmuQ6aof5cP7AT9gj5kTD4Z7BLdXlqvtpJAyMJrWIGSRaXy9QVhkqHU6oXm
+UKxosEO8zlcVH8jM9omAG8XOd9+KAqlR/nFQMX8AEQEAAYkDbAQYAQoAIBYhBHGo
+EuN0oqgnTRz+ZltcNEJRpdp+BQJXAZJjAhsCAcAJEFtcNEJRpdp+wPQgBBkBCgAd
+FiEE4gkjKPkt/ksh70dUtjZz25idcjMFAlcBkmMACgkQtjZz25idcjN7cwv+Kjou
+3GApBRTteGLBwJjf5KlrJYo/YRSWqZG6HtR9E++AkOh2/Dl0wL77mwWExzsA0+WI
+nsWiq4QxWWmlEZLuJ3shXKzjouRpazW1bXOE+jKXPtcuIX8gWb9ms3V2czQHCX2c
+cEN/zo8A5K5LdCB/76weIROkZHb0AO7nME/sz1Ja8QzKOaMDM8xlBt7tMifbqB3j
+dy0UmJUeNFttWzPfe1Nv2vTHHhE8WhccoT50bXYs5bPTrvIrtr4ZsfYnUcFxe1cg
+a8n5zb2I60YB9akvc4/9Io37QXeHBNFkEMj2ivwpo4j7l9cklno/O5D6FtbIjJFe
+PVzxqdcHHKxvb1nF5/BpugHCOO3SxMzukaewFRlBxmsg3tEvoaNviLGsy87skhoK
+I0WL3GGASzkkCoMmuG6s3jv23zxYQ55bHLtEiv3e/VWgntWk1jePm97nlLcbkEww
+k2tH0skoFQV73/5m3Ys2AaDaUctk+h18o3z0qQRRoEiGlEMkEpCHjBrUGAAL2NwL
+/1RDeMNIzMeINdRgTtN1ckzv6rJ3Y9uAV8bcmdY6/9gl5sH6k+Kce0ViF4mBNDW2
+sIlXhtn0ULGpxc3r7XGf6n8VDEtL+pI/vVCoopvKPEWLbYZAF9xHVRiYYUX6ikRX
+dXObqJAemErpnEMZq4aXsjQs8n9fnzOI2uut+gum2xu2LRvbiepAbt4kjWkEtZ8U
+nj8YNraeB9Dhr5uZ6JqeXc5fOpLiDI7O6250hEWvTX3+rh8055B6b4nI/g8kYCiM
+WueITj/0UKe3OeZO9BB/G7UhM83HoMgUHMH+RPcuyWmn/XSR95WYNUgAs1nxi1jq
+17cqU9TMSCULhgtds4zJXsbmGUX8+iJAy52gD//BZswDJRJe9YDS5LaMgQgM2XiI
+pVyan8lQMzHvxXx638lh7gbzkqM4Zc7TQ8G/KruBvh4Vvt4m0ppZooiF8b9QiqS3
+BD7QblDB8QAGLcLwzAM0uJv33ylHf70U/dLIg7IcBp5NAg6WuvaCfYefn+vNQqD6
+tA==
+=nDSP
+-----END PGP PUBLIC KEY BLOCK-----
diff -Nru thunderbird-91.7.0+build2/comm/mail/test/browser/shared-modules/OpenPGPTestUtils.jsm thunderbird-91.8.1+build1/comm/mail/test/browser/shared-modules/OpenPGPTestUtils.jsm
--- thunderbird-91.7.0+build2/comm/mail/test/browser/shared-modules/OpenPGPTestUtils.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/test/browser/shared-modules/OpenPGPTestUtils.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -188,7 +188,8 @@
fingerPrintObj,
false,
[],
- isSecret
+ isSecret,
+ false
);
if (result !== 0) {
diff -Nru thunderbird-91.7.0+build2/comm/mail/themes/shared/mail/aboutSupport.css thunderbird-91.8.1+build1/comm/mail/themes/shared/mail/aboutSupport.css
--- thunderbird-91.7.0+build2/comm/mail/themes/shared/mail/aboutSupport.css 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mail/themes/shared/mail/aboutSupport.css 2022-04-15 07:49:21.000000000 +0000
@@ -2,6 +2,24 @@
* 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/. */
+@media (-moz-toolbar-prefers-color-scheme: dark) {
+ :root {
+ --in-content-button-background: rgba(249, 249, 250, 0.1);
+ --in-content-button-background-hover: rgba(249, 249, 250, 0.15);
+ --in-content-button-background-active: rgba(249, 249, 250, 0.2);
+ --in-content-primary-button-background: #45a1ff;
+ --in-content-primary-button-background-hover: #65c1ff;
+ --in-content-primary-button-background-active: #85e1ff;
+ --in-content-focus-outline-color: #45a1ff;
+ --in-content-table-header-color: rgb(43, 42, 51);
+ --in-content-table-header-background: var(--in-content-primary-button-background);
+ }
+}
+
+th {
+ border-color: color-mix(in srgb, currentColor 41%, transparent);
+}
+
.data-public {
display: none;
}
@@ -21,12 +39,12 @@
}
.thead-level2 > th {
- background-color: #ebebeb;
- color: #333;
+ background-color: hsl(0, 0%, 60%);
}
td.data-private {
background-color: #ff9;
+ color: #333;
}
.calendar-table > thead > th:nth-of-type(1) {
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/addrbook/modules/SQLiteDirectory.jsm thunderbird-91.8.1+build1/comm/mailnews/addrbook/modules/SQLiteDirectory.jsm
--- thunderbird-91.7.0+build2/comm/mailnews/addrbook/modules/SQLiteDirectory.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/addrbook/modules/SQLiteDirectory.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -173,6 +173,8 @@
super.init(uri);
directories.set(fileName, this);
+ // Create the DB connection here already, to let init() throw on corrupt SQLite files.
+ this._dbConnection;
}
async cleanUp() {
await super.cleanUp();
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/addrbook/test/unit/test_collection_2.js thunderbird-91.8.1+build1/comm/mailnews/addrbook/test/unit/test_collection_2.js
--- thunderbird-91.7.0+build2/comm/mailnews/addrbook/test/unit/test_collection_2.js 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/addrbook/test/unit/test_collection_2.js 2022-04-15 07:49:21.000000000 +0000
@@ -9,9 +9,10 @@
var nsIAbPMF = Ci.nsIAbPreferMailFormat;
function run_test() {
- // Test - Get the address collecter
+ // Test - Get the address collector
+ loadABFile("data/collect", kPABData.fileName);
- // Get the actual collecter
+ // Get the actual collector
var addressCollect = Cc[
"@mozilla.org/addressbook/services/addressCollector;1"
].getService(Ci.nsIAbAddressCollector);
@@ -19,10 +20,8 @@
// Set the new pref afterwards to ensure we change correctly
Services.prefs.setCharPref("mail.collect_addressbook", kCABData.URI);
- loadABFile("data/collect", kPABData.fileName);
-
// XXX Getting all directories ensures we create all ABs because the
- // address collecter can't currently create ABs itself (bug 314448).
+ // address collector can't currently create ABs itself (bug 314448).
MailServices.ab.directories;
addressCollect.collectAddress(
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/base/src/MailNotificationManager.jsm thunderbird-91.8.1+build1/comm/mailnews/base/src/MailNotificationManager.jsm
--- thunderbird-91.7.0+build2/comm/mailnews/base/src/MailNotificationManager.jsm 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/base/src/MailNotificationManager.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -195,16 +195,16 @@
return;
}
- let numNewMessages = folder.getNumNewMessages(false);
- let msgDb = folder.msgDatabase;
- let newMsgKeys = msgDb.getNewList().slice(-numNewMessages);
- if (newMsgKeys.length == 0) {
+ let newMsgKeys = this._getNewMsgKeysNotNotified(folder);
+ let numNewMessages = newMsgKeys.length;
+ if (!numNewMessages) {
return;
}
+
this._logger.debug(
`Filling alert info; folder.URI=${folder.URI}, numNewMessages=${numNewMessages}`
);
- let firstNewMsgHdr = msgDb.GetMsgHdrForKey(newMsgKeys[0]);
+ let firstNewMsgHdr = folder.msgDatabase.GetMsgHdrForKey(newMsgKeys[0]);
let title = this._getAlertTitle(folder, numNewMessages);
let body;
@@ -363,6 +363,8 @@
// The use_system_alert pref is false or showAlert somehow failed, use the
// customized alert window.
this._showCustomizedAlert(folder);
+
+ this._folderBiffTime.set(folder, Date.now());
}
/**
@@ -372,43 +374,27 @@
* @param {nsIMsgFolder} [folder] - The folder containing new messages.
*/
_showCustomizedAlert(folder) {
- let newMsgKeys;
- if (folder) {
- // Show this folder or queue it.
- newMsgKeys = folder.msgDatabase
- .getNewList()
- .slice(-folder.getNumNewMessages(false));
- if (this._customizedAlertShown) {
- this._pendingFolders.add(folder);
- return;
- }
- } else {
+ if (this._customizedAlertShown) {
+ // Queue the folder.
+ this._pendingFolders.add(folder);
+ return;
+ }
+ if (!folder) {
// Get the next folder from the queue.
folder = this._pendingFolders.keys().next().value;
if (!folder) {
return;
}
- let msgDb = folder.msgDatabase;
- let lastBiffTime = this._folderBiffTime.get(folder) || 0;
- newMsgKeys = msgDb.getNewList().filter(key => {
- // It's possible that after we queued the folder, user has opened the
- // folder and read some new messages. We compare the timestamp of each
- // NEW message with the last biff time to make sure only real NEW
- // messages are alerted.
- let msgHdr = msgDb.GetMsgHdrForKey(key);
- return msgHdr.dateInSeconds * 1000 > lastBiffTime;
- });
-
this._pendingFolders.delete(folder);
}
- if (newMsgKeys.length == 0) {
+
+ let newMsgKeys = this._getNewMsgKeysNotNotified(folder);
+ if (!newMsgKeys.length) {
// No NEW message in the current folder, try the next queued folder.
this._showCustomizedAlert();
return;
}
- this._folderBiffTime.set(folder, Date.now());
-
let args = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
args.appendElement(folder);
args.appendElement({
@@ -425,6 +411,23 @@
this._customizedAlertShown = true;
}
+ /**
+ * Get all NEW messages from a folder that we received after last biff time.
+ * @param {nsIMsgFolder} folder - The message folder to check.
+ * @returns {number[]} An array of message keys.
+ */
+ _getNewMsgKeysNotNotified(folder) {
+ let msgDb = folder.msgDatabase;
+ let lastBiffTime = this._folderBiffTime.get(folder) || 0;
+ return msgDb
+ .getNewList()
+ .slice(-folder.getNumNewMessages(false))
+ .filter(key => {
+ let msgHdr = msgDb.GetMsgHdrForKey(key);
+ return msgHdr.dateInSeconds * 1000 > lastBiffTime;
+ });
+ }
+
async _updateUnreadCount() {
if (this._updatingUnreadCount) {
// _updateUnreadCount can be triggered faster than we finish rendering the
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/compose/src/MessageSend.jsm thunderbird-91.8.1+build1/comm/mailnews/compose/src/MessageSend.jsm
--- thunderbird-91.7.0+build2/comm/mailnews/compose/src/MessageSend.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/compose/src/MessageSend.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -328,7 +328,11 @@
fail(exitCode, errorMsg) {
this._failed = true;
let prompt = this.getDefaultPrompt();
- if (!Components.isSuccessCode(exitCode) && prompt) {
+ if (
+ !Components.isSuccessCode(exitCode) &&
+ exitCode != Cr.NS_ERROR_ABORT &&
+ prompt
+ ) {
MsgUtils.sendLogger.error(
`Sending failed; ${errorMsg}, exitCode=${exitCode}, originalMsgURI=${this._originalMsgURI}`
);
@@ -590,15 +594,15 @@
);
isNSSError = true;
} catch (e) {
- if (errorName == "sendFailed") {
+ if (url.errorMessage) {
+ // url.errorMessage is an already localized message, usually
+ // combined with the error message from SMTP server.
+ errorMsg = url.errorMessage;
+ } else if (errorName != "sendFailed") {
// Not the default string. A mailnews error occurred that does not
// require the server name to be encoded. Just print the descriptive
// string.
errorMsg = this._composeBundle.GetStringFromName(errorName);
- } else if (url.errorMessage) {
- // url.errorMessage is an already localized message, usually
- // combined with the error message from SMTP server.
- errorMsg = url.errorMessage;
} else {
errorMsg = this._composeBundle.GetStringFromName(
"sendFailedUnexpected"
@@ -669,7 +673,6 @@
exitCode = MsgUtils.NS_ERROR_SMTP_SEND_FAILED_REFUSED;
break;
case Cr.NS_ERROR_NET_INTERRUPT:
- case Cr.NS_ERROR_ABORT:
exitCode = MsgUtils.NS_ERROR_SMTP_SEND_FAILED_INTERRUPTED;
break;
case Cr.NS_ERROR_NET_TIMEOUT:
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/compose/src/SmtpClient.jsm thunderbird-91.8.1+build1/comm/mailnews/compose/src/SmtpClient.jsm
--- thunderbird-91.7.0+build2/comm/mailnews/compose/src/SmtpClient.jsm 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/compose/src/SmtpClient.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -139,6 +139,7 @@
* Sends QUIT
*/
quit() {
+ this._authenticating = false;
this._sendCommand("QUIT");
this._currentAction = this.close;
}
@@ -633,7 +634,7 @@
// According to rfc4616#section-2, password should be UTF-8 BinaryString
// before base64 encoded.
let password = String.fromCharCode(
- ...new TextEncoder().encode(this._authenticator.getPassword())
+ ...new TextEncoder().encode(this._getPassword())
);
this._sendCommand(
@@ -910,7 +911,20 @@
}
}
- this._authenticateUser();
+ if (
+ command.data.match(/\bCLIENTID\b/) &&
+ (this._secureTransport ||
+ // For test purpose.
+ ["localhost", "127.0.0.1", "::1"].includes(this._server.hostname)) &&
+ this._server.clientidEnabled &&
+ this._server.clientid
+ ) {
+ // Client identity extension, still a draft.
+ this._currentAction = this._actionCLIENTID;
+ this._sendCommand("CLIENTID UUID " + this._server.clientid, true);
+ } else {
+ this._authenticateUser();
+ }
}
/**
@@ -948,6 +962,39 @@
}
/**
+ * Handles server response for CLIENTID command. If successful then will
+ * initiate the authenticateUser process.
+ *
+ * @param {Object} command Parsed command from the server {statusCode, data}
+ */
+ _actionCLIENTID(command) {
+ if (!command.success) {
+ this._onNsError(MsgUtils.NS_ERROR_SMTP_SERVER_ERROR, command.data);
+ return;
+ }
+ this._authenticateUser();
+ }
+
+ /**
+ * Returns the saved/cached server password, or show a password dialog. If the
+ * user cancels the dialog, abort sending.
+ * @returns {string} The server password.
+ */
+ _getPassword() {
+ try {
+ return this._authenticator.getPassword();
+ } catch (e) {
+ if (e.result == Cr.NS_ERROR_ABORT) {
+ this.quit();
+ this.onerror(e.result);
+ } else {
+ throw e;
+ }
+ }
+ return null;
+ }
+
+ /**
* Response to AUTH LOGIN, if successful expects base64 encoded username
*
* @param {Object} command Parsed command from the server {statusCode, data}
@@ -974,7 +1021,7 @@
}
this.logger.debug("AUTH LOGIN PASS");
this._currentAction = this._actionAUTHComplete;
- let password = this._authenticator.getPassword();
+ let password = this._getPassword();
if (
!Services.prefs.getBoolPref(
"mail.smtp_login_pop3_user_pass_auth_is_latin1",
@@ -1002,7 +1049,7 @@
}
// Server sent us a base64 encoded challenge.
let challenge = atob(command.data);
- let password = this._authenticator.getPassword();
+ let password = this._getPassword();
// Use password as key, challenge as payload, generate a HMAC-MD5 signature.
let signature = MailCryptoUtils.hmacMd5(
new TextEncoder().encode(password),
@@ -1097,7 +1144,7 @@
* @param {Object} command Parsed command from the server {statusCode, data}
*/
_actionIdle(command) {
- this._onError(new Error(command.data));
+ this._onNsError(MsgUtils.NS_ERROR_SMTP_SERVER_ERROR, command.data);
}
/**
@@ -1247,7 +1294,11 @@
}
this._currentAction = this._actionIdle;
- this.ondone(command.success ? 0 : MsgUtils.NS_ERROR_SENDING_MESSAGE);
+ if (command.success) {
+ this.ondone(0);
+ } else {
+ this._onNsError(MsgUtils.NS_ERROR_SENDING_MESSAGE, command.data);
+ }
}
// If the client wanted to do something else (eg. to quit), do not force idle
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/compose/src/SmtpServer.jsm thunderbird-91.8.1+build1/comm/mailnews/compose/src/SmtpServer.jsm
--- thunderbird-91.7.0+build2/comm/mailnews/compose/src/SmtpServer.jsm 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/compose/src/SmtpServer.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -231,6 +231,8 @@
this.username = outUsername.value;
}
this.password = outPassword.value;
+ } else {
+ throw Components.Exception("Password dialog canceled", Cr.NS_ERROR_ABORT);
}
return this.password;
},
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/compose/test/unit/test_smtpClient.js thunderbird-91.8.1+build1/comm/mailnews/compose/test/unit/test_smtpClient.js
--- thunderbird-91.7.0+build2/comm/mailnews/compose/test/unit/test_smtpClient.js 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/compose/test/unit/test_smtpClient.js 2022-04-15 07:49:21.000000000 +0000
@@ -0,0 +1,97 @@
+/* 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/. */
+
+const { PromiseTestUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/PromiseTestUtils.jsm"
+);
+
+let server = setupServerDaemon();
+server.start();
+registerCleanupFunction(() => {
+ server.stop();
+});
+
+/**
+ * Test sending is aborted when alwaysSTARTTLS is set, but the server doesn't
+ * support STARTTLS.
+ */
+add_task(async function testAbort() {
+ server.resetTest();
+ let smtpServer = getBasicSmtpServer(server.port);
+ let identity = getSmtpIdentity("identity@foo.invalid", smtpServer);
+ // Set to always use STARTTLS.
+ smtpServer.socketType = Ci.nsMsgSocketType.alwaysSTARTTLS;
+
+ do_test_pending();
+
+ let urlListener = {
+ OnStartRunningUrl(url) {},
+ OnStopRunningUrl(url, status) {
+ // Test sending is aborted with NS_ERROR_STARTTLS_FAILED_EHLO_STARTTLS.
+ Assert.equal(status, 0x80553126);
+ do_test_finished();
+ },
+ };
+
+ // Send a message.
+ let testFile = do_get_file("data/message1.eml");
+ MailServices.smtp.sendMailMessage(
+ testFile,
+ "to@foo.invalid",
+ identity,
+ "from@foo.invalid",
+ null,
+ urlListener,
+ null,
+ null,
+ false,
+ "",
+ {},
+ {}
+ );
+ server.performTest();
+});
+
+/**
+ * Test client identity extension works.
+ */
+add_task(async function testClientIdentityExtension() {
+ server.resetTest();
+ let smtpServer = getBasicSmtpServer(server.port);
+ let identity = getSmtpIdentity("identity@foo.invalid", smtpServer);
+ // Enable and set clientid to the smtp server.
+ smtpServer.clientidEnabled = true;
+ smtpServer.clientid = "uuid-111";
+
+ // Send a message.
+ let asyncUrlListener = new PromiseTestUtils.PromiseUrlListener();
+ let testFile = do_get_file("data/message1.eml");
+ MailServices.smtp.sendMailMessage(
+ testFile,
+ "to@foo.invalid",
+ identity,
+ "from@foo.invalid",
+ null,
+ asyncUrlListener,
+ null,
+ null,
+ false,
+ "",
+ {},
+ {}
+ );
+ server.performTest();
+
+ await asyncUrlListener.promise;
+
+ // Check CLIENTID command is sent.
+ let transaction = server.playTransaction();
+ do_check_transaction(transaction, [
+ "EHLO test",
+ "CLIENTID UUID uuid-111",
+ "MAIL FROM: BODY=8BITMIME SIZE=159",
+ "RCPT TO:",
+ "DATA",
+ ]);
+});
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/compose/test/unit/xpcshell-jsm.ini thunderbird-91.8.1+build1/comm/mailnews/compose/test/unit/xpcshell-jsm.ini
--- thunderbird-91.7.0+build2/comm/mailnews/compose/test/unit/xpcshell-jsm.ini 2022-03-07 21:35:19.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/compose/test/unit/xpcshell-jsm.ini 2022-04-15 07:49:21.000000000 +0000
@@ -9,5 +9,6 @@
# For some reason this fails with the C++ modules.
[test_createAndSendMessage.js]
+[test_smtpClient.js]
[include:xpcshell-shared.ini]
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/mime/src/mimecont.cpp thunderbird-91.8.1+build1/comm/mailnews/mime/src/mimecont.cpp
--- thunderbird-91.7.0+build2/comm/mailnews/mime/src/mimecont.cpp 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/mime/src/mimecont.cpp 2022-04-15 07:49:21.000000000 +0000
@@ -57,7 +57,24 @@
/* Do this first so that children have their parse_eof methods called
in forward order (0-N) but are destroyed in backward order (N-0)
*/
- if (!object->closed_p) object->clazz->parse_eof(object, false);
+
+ /* If we're being destroyed, prior to deleting any data, mark
+ * flush data in all childs and mark them as closed, to avoid
+ * flushing during subsequent mime_free of childs.
+ * This also helps if this (parent) object is already marked as
+ * closed, but a child is not yet marked as closed.
+ */
+ ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_eof(object, true);
+ if (cont->children) {
+ int i;
+ for (i = 0; i < cont->nchildren; i++) {
+ MimeObject* kid = cont->children[i];
+ if (kid && !kid->closed_p) {
+ kid->clazz->parse_eof(kid, true);
+ }
+ }
+ }
+
if (!object->parsed_p) object->clazz->parse_end(object, false);
if (cont->children) {
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/mime/src/mimehdrs.cpp thunderbird-91.8.1+build1/comm/mailnews/mime/src/mimehdrs.cpp
--- thunderbird-91.7.0+build2/comm/mailnews/mime/src/mimehdrs.cpp 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/mime/src/mimehdrs.cpp 2022-04-15 07:49:21.000000000 +0000
@@ -163,10 +163,65 @@
return hdrs2;
}
+static bool find_header_starts(MimeHeaders* hdrs, bool counting) {
+ const char* end = hdrs->all_headers + hdrs->all_headers_fp;
+ char* s = hdrs->all_headers;
+ int i = 0;
+
+ if (counting) {
+ // For the start pointer
+ hdrs->heads_size = 1;
+ } else {
+ hdrs->heads[i++] = hdrs->all_headers;
+ }
+
+ while (s < end) {
+ SEARCH_NEWLINE:
+ while (s < end && *s != '\r' && *s != '\n') s++;
+
+ if (s >= end) break;
+
+ /* If "\r\n " or "\r\n\t" is next, that doesn't terminate the header. */
+ else if (s + 2 < end && (s[0] == '\r' && s[1] == '\n') &&
+ (s[2] == ' ' || s[2] == '\t')) {
+ s += 3;
+ goto SEARCH_NEWLINE;
+ }
+ /* If "\r " or "\r\t" or "\n " or "\n\t" is next, that doesn't terminate
+ the header either. */
+ else if (s + 1 < end && (s[0] == '\r' || s[0] == '\n') &&
+ (s[1] == ' ' || s[1] == '\t')) {
+ s += 2;
+ goto SEARCH_NEWLINE;
+ }
+
+ /* At this point, `s' points before a header-terminating newline.
+ Move past that newline, and store that new position in `heads'.
+ */
+ if (*s == '\r') s++;
+
+ if (s >= end) break;
+
+ if (*s == '\n') s++;
+
+ if (s < end) {
+ if (counting) {
+ hdrs->heads_size++;
+ } else {
+ NS_ASSERTION(i < hdrs->heads_size,
+ "1.1 19 Mar 1999 12:00");
+ if (i >= hdrs->heads_size) return false;
+ hdrs->heads[i++] = s;
+ }
+ }
+ }
+ if (!counting) {
+ NS_ASSERTION(i == hdrs->heads_size, "unexpected");
+ }
+ return true;
+}
+
int MimeHeaders_build_heads_list(MimeHeaders* hdrs) {
- char* s;
- char* end;
- int i;
NS_ASSERTION(hdrs, "1.1 19 Mar 1999 12:00");
if (!hdrs) return -1;
@@ -195,68 +250,19 @@
}
}
- /* First go through and count up the number of headers in the block.
- */
- end = hdrs->all_headers + hdrs->all_headers_fp;
- for (s = hdrs->all_headers; s < end; s++) {
- if (s < (end - 1) && s[0] == '\r' && s[1] == '\n') /* CRLF -> LF */
- s++;
-
- if ((s[0] == '\r' || s[0] == '\n') && /* we're at a newline, and */
- (s >= (end - 1) || /* we're at EOF, or */
- !(s[1] == ' ' || s[1] == '\t'))) /* next char is nonwhite */
- hdrs->heads_size++;
- }
+ find_header_starts(hdrs, true);
/* Now allocate storage for the pointers to each of those headers.
*/
- hdrs->heads = (char**)PR_MALLOC((hdrs->heads_size + 1) * sizeof(char*));
+ hdrs->heads = (char**)PR_MALLOC((hdrs->heads_size) * sizeof(char*));
if (!hdrs->heads) return MIME_OUT_OF_MEMORY;
- memset(hdrs->heads, 0, (hdrs->heads_size + 1) * sizeof(char*));
+ memset(hdrs->heads, 0, (hdrs->heads_size) * sizeof(char*));
/* Now make another pass through the headers, and this time, record the
starting position of each header.
*/
-
- i = 0;
- hdrs->heads[i++] = hdrs->all_headers;
- s = hdrs->all_headers;
-
- while (s < end) {
- SEARCH_NEWLINE:
- while (s < end && *s != '\r' && *s != '\n') s++;
-
- if (s >= end) break;
-
- /* If "\r\n " or "\r\n\t" is next, that doesn't terminate the header. */
- else if (s + 2 < end && (s[0] == '\r' && s[1] == '\n') &&
- (s[2] == ' ' || s[2] == '\t')) {
- s += 3;
- goto SEARCH_NEWLINE;
- }
- /* If "\r " or "\r\t" or "\n " or "\n\t" is next, that doesn't terminate
- the header either. */
- else if (s + 1 < end && (s[0] == '\r' || s[0] == '\n') &&
- (s[1] == ' ' || s[1] == '\t')) {
- s += 2;
- goto SEARCH_NEWLINE;
- }
-
- /* At this point, `s' points before a header-terminating newline.
- Move past that newline, and store that new position in `heads'.
- */
- if (*s == '\r') s++;
-
- if (s >= end) break;
-
- if (*s == '\n') s++;
-
- if (s < end) {
- NS_ASSERTION(!(i > hdrs->heads_size),
- "1.1 19 Mar 1999 12:00");
- if (i > hdrs->heads_size) return -1;
- hdrs->heads[i++] = s;
- }
+ if (!find_header_starts(hdrs, false)) {
+ return -1;
}
return 0;
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/mime/src/mimeobj.cpp thunderbird-91.8.1+build1/comm/mailnews/mime/src/mimeobj.cpp
--- thunderbird-91.7.0+build2/comm/mailnews/mime/src/mimeobj.cpp 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/mime/src/mimeobj.cpp 2022-04-15 07:49:21.000000000 +0000
@@ -235,6 +235,10 @@
}
static int MimeObject_parse_eof(MimeObject* obj, bool abort_p) {
+ if (abort_p) {
+ obj->closed_p = true;
+ return 0;
+ }
if (obj->closed_p) return 0;
NS_ASSERTION(!obj->parsed_p, "obj already parsed");
@@ -243,7 +247,7 @@
the parse_line method will be called with a string with no trailing
newline, which isn't the usual case.)
*/
- if (!abort_p && obj->ibuffer_fp > 0) {
+ if (obj->ibuffer_fp > 0) {
int status = obj->clazz->parse_line(obj->ibuffer, obj->ibuffer_fp, obj);
obj->ibuffer_fp = 0;
if (status < 0) {
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/mime/src/modlmime.h thunderbird-91.8.1+build1/comm/mailnews/mime/src/modlmime.h
--- thunderbird-91.7.0+build2/comm/mailnews/mime/src/modlmime.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/mime/src/modlmime.h 2022-04-15 07:49:21.000000000 +0000
@@ -33,14 +33,15 @@
bool done_p; /* Whether we've read the end-of-headers marker
(the terminating blank line.) */
- char** heads; /* An array of length n_headers which points
+ char** heads; /* An array of length heads_size which points
to the beginning of each distinct header:
just after the newline which terminated
the previous one. This is to speed search.
This is not initialized until all the
headers have been read.
*/
- int32_t heads_size; /* The length (and consequently, how many
+ int32_t heads_size; /* The number of entries (pointers) in the heads
+ array (and consequently, how many
distinct headers are in here.) */
char* obuffer; /* This buffer is used for output. */
diff -Nru thunderbird-91.7.0+build2/comm/mailnews/test/fakeserver/Smtpd.jsm thunderbird-91.8.1+build1/comm/mailnews/test/fakeserver/Smtpd.jsm
--- thunderbird-91.7.0+build2/comm/mailnews/test/fakeserver/Smtpd.jsm 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/mailnews/test/fakeserver/Smtpd.jsm 2022-04-15 07:49:21.000000000 +0000
@@ -43,7 +43,7 @@
kUsername: "testsmtp",
kPassword: "smtptest",
kAuthSchemes: ["CRAM-MD5", "PLAIN", "LOGIN"],
- kCapabilities: ["8BITMIME", "SIZE"],
+ kCapabilities: ["8BITMIME", "SIZE", "CLIENTID"],
_nextAuthFunction: undefined,
resetTest() {
@@ -63,6 +63,9 @@
capa += "\n250 HELP"; // the odd one: no "-", per RFC 2821
return capa;
},
+ CLIENTID(args) {
+ return "250 ok";
+ },
AUTH(lineRest) {
if (this._state == kStateAuthenticated) {
return "503 You're already authenticated";
diff -Nru thunderbird-91.7.0+build2/comm/SOURCE_CHANGESET thunderbird-91.8.1+build1/comm/SOURCE_CHANGESET
--- thunderbird-91.7.0+build2/comm/SOURCE_CHANGESET 2022-03-07 21:35:21.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/SOURCE_CHANGESET 2022-04-15 07:49:38.000000000 +0000
@@ -1 +1 @@
-39ccd0b9ea033f3292af90667e470b98a79eb8c9
\ No newline at end of file
+79f1a34ff6596c36fd01ceee26ae1881cebc4756
\ No newline at end of file
diff -Nru thunderbird-91.7.0+build2/comm/taskcluster/scripts/build-libotr.sh thunderbird-91.8.1+build1/comm/taskcluster/scripts/build-libotr.sh
--- thunderbird-91.7.0+build2/comm/taskcluster/scripts/build-libotr.sh 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/taskcluster/scripts/build-libotr.sh 2022-04-15 07:49:21.000000000 +0000
@@ -140,7 +140,7 @@
case "${_TARGET_OS}" in
win*)
cd src
- "${CC}" -static-libgcc -shared -Wl,-no-undefined ${LDFLAGS} -o libotr.dll \
+ "${CC}" -static-libgcc -s -shared -Wl,-no-undefined ${LDFLAGS} -o libotr.dll \
*.o \
-L"${_PREFIX}/lib" "${_PREFIX}/lib/libgcrypt.a" "${_PREFIX}/lib/libgpg-error.a" \
-L"${_LIBDIR}" -lws2_32 -lssp
diff -Nru thunderbird-91.7.0+build2/comm/third_party/botan/botan.mozbuild thunderbird-91.8.1+build1/comm/third_party/botan/botan.mozbuild
--- thunderbird-91.7.0+build2/comm/third_party/botan/botan.mozbuild 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/botan/botan.mozbuild 2022-04-15 07:49:21.000000000 +0000
@@ -44,7 +44,7 @@
botan_build = GENERATED_FILES['build/build.h']
botan_build.script = 'botan_configure.py'
botan_build.flags = [
- '--cc-bin={}'.format(CONFIG['MZLA_RNP_CXX']),
+ '--cc-bin={}'.format(CONFIG['CXX']),
'--cpu={}'.format(CONFIG['target_cpu']),
'--os={}'.format(botan_os),
'--with-build-dir={}'.format(OBJDIR),
@@ -56,9 +56,6 @@
'--with-cmake',
]
- # clock_gettime is not part of OSX until 10.12 sdk, Taskcluster builds with 10.11
- if CONFIG['OS_ARCH'] == 'Darwin':
- botan_build.flags.append('--without-os-features=clock_gettime')
LOCAL_INCLUDES = ['!build/include']
diff -Nru thunderbird-91.7.0+build2/comm/third_party/bzip2/moz.build thunderbird-91.8.1+build1/comm/third_party/bzip2/moz.build
--- thunderbird-91.7.0+build2/comm/third_party/bzip2/moz.build 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/bzip2/moz.build 2022-04-15 07:49:22.000000000 +0000
@@ -13,6 +13,10 @@
else:
include("../rnpdefs.mozbuild")
+ COMPILE_FLAGS["WARNINGS_CFLAGS"] += [
+ "-Wno-unreachable-code-return",
+ ]
+
SOURCES += [
"blocksort.c",
"bzlib.c",
diff -Nru thunderbird-91.7.0+build2/comm/third_party/defs.mk thunderbird-91.8.1+build1/comm/third_party/defs.mk
--- thunderbird-91.7.0+build2/comm/third_party/defs.mk 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/defs.mk 1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-# 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/.
-
-# This file is included my mozbuild for this directory and any subdirectories
-# that use mozbuild. Currently the OTR libraries do not use mozbuild and
-# are not affected.
-
-# MZLA_RNP_CC and MZLA_RNP_CXX are set in openpgp.configure and are used
-# to remove the -std= flags from the commands.
-CC := $(MZLA_RNP_CC)
-CXX := $(MZLA_RNP_CXX)
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/arraylist.c thunderbird-91.8.1+build1/comm/third_party/json-c/arraylist.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/arraylist.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/arraylist.c 2022-04-15 07:49:21.000000000 +0000
@@ -14,12 +14,12 @@
#include
#ifdef STDC_HEADERS
-# include
-# include
+#include
+#include
#endif /* STDC_HEADERS */
#if defined(HAVE_STRINGS_H) && !defined(_STRING_H) && !defined(__USE_BSD)
-# include
+#include
#endif /* HAVE_STRINGS_H */
#ifndef SIZE_T_MAX
@@ -36,111 +36,166 @@
#include "arraylist.h"
-struct array_list*
-array_list_new(array_list_free_fn *free_fn)
+struct array_list *array_list_new(array_list_free_fn *free_fn)
{
- struct array_list *arr;
+ return array_list_new2(free_fn, ARRAY_LIST_DEFAULT_SIZE);
+}
+
+struct array_list *array_list_new2(array_list_free_fn *free_fn, int initial_size)
+{
+ struct array_list *arr;
- arr = (struct array_list*)calloc(1, sizeof(struct array_list));
- if(!arr) return NULL;
- arr->size = ARRAY_LIST_DEFAULT_SIZE;
- arr->length = 0;
- arr->free_fn = free_fn;
- if(!(arr->array = (void**)calloc(sizeof(void*), arr->size))) {
- free(arr);
- return NULL;
- }
- return arr;
-}
-
-extern void
-array_list_free(struct array_list *arr)
-{
- size_t i;
- for(i = 0; i < arr->length; i++)
- if(arr->array[i]) arr->free_fn(arr->array[i]);
- free(arr->array);
- free(arr);
+ arr = (struct array_list *)malloc(sizeof(struct array_list));
+ if (!arr)
+ return NULL;
+ arr->size = initial_size;
+ arr->length = 0;
+ arr->free_fn = free_fn;
+ if (!(arr->array = (void **)malloc(arr->size * sizeof(void *))))
+ {
+ free(arr);
+ return NULL;
+ }
+ return arr;
}
-void*
-array_list_get_idx(struct array_list *arr, size_t i)
+extern void array_list_free(struct array_list *arr)
{
- if(i >= arr->length) return NULL;
- return arr->array[i];
+ size_t i;
+ for (i = 0; i < arr->length; i++)
+ if (arr->array[i])
+ arr->free_fn(arr->array[i]);
+ free(arr->array);
+ free(arr);
+}
+
+void *array_list_get_idx(struct array_list *arr, size_t i)
+{
+ if (i >= arr->length)
+ return NULL;
+ return arr->array[i];
}
static int array_list_expand_internal(struct array_list *arr, size_t max)
{
- void *t;
- size_t new_size;
+ void *t;
+ size_t new_size;
- if(max < arr->size) return 0;
- /* Avoid undefined behaviour on size_t overflow */
- if( arr->size >= SIZE_T_MAX / 2 )
- new_size = max;
- else
- {
- new_size = arr->size << 1;
- if (new_size < max)
- new_size = max;
- }
- if (new_size > (~((size_t)0)) / sizeof(void*)) return -1;
- if (!(t = realloc(arr->array, new_size*sizeof(void*)))) return -1;
- arr->array = (void**)t;
- (void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*));
- arr->size = new_size;
- return 0;
+ if (max < arr->size)
+ return 0;
+ /* Avoid undefined behaviour on size_t overflow */
+ if (arr->size >= SIZE_T_MAX / 2)
+ new_size = max;
+ else
+ {
+ new_size = arr->size << 1;
+ if (new_size < max)
+ new_size = max;
+ }
+ if (new_size > (~((size_t)0)) / sizeof(void *))
+ return -1;
+ if (!(t = realloc(arr->array, new_size * sizeof(void *))))
+ return -1;
+ arr->array = (void **)t;
+ arr->size = new_size;
+ return 0;
}
-int
-array_list_put_idx(struct array_list *arr, size_t idx, void *data)
+int array_list_shrink(struct array_list *arr, size_t empty_slots)
{
- if (idx > SIZE_T_MAX - 1 ) return -1;
- if(array_list_expand_internal(arr, idx+1)) return -1;
- if(idx < arr->length && arr->array[idx])
- arr->free_fn(arr->array[idx]);
- arr->array[idx] = data;
- if(arr->length <= idx) arr->length = idx + 1;
- return 0;
+ void *t;
+ size_t new_size;
+
+ new_size = arr->length + empty_slots;
+ if (new_size == arr->size)
+ return 0;
+ if (new_size > arr->size)
+ return array_list_expand_internal(arr, new_size);
+ if (new_size == 0)
+ new_size = 1;
+
+ if (!(t = realloc(arr->array, new_size * sizeof(void *))))
+ return -1;
+ arr->array = (void **)t;
+ arr->size = new_size;
+ return 0;
+}
+
+//static inline int _array_list_put_idx(struct array_list *arr, size_t idx, void *data)
+int array_list_put_idx(struct array_list *arr, size_t idx, void *data)
+{
+ if (idx > SIZE_T_MAX - 1)
+ return -1;
+ if (array_list_expand_internal(arr, idx + 1))
+ return -1;
+ if (idx < arr->length && arr->array[idx])
+ arr->free_fn(arr->array[idx]);
+ arr->array[idx] = data;
+ if (idx > arr->length)
+ {
+ /* Zero out the arraylist slots in between the old length
+ and the newly added entry so we know those entries are
+ empty.
+ e.g. when setting array[7] in an array that used to be
+ only 5 elements longs, array[5] and array[6] need to be
+ set to 0.
+ */
+ memset(arr->array + arr->length, 0, (idx - arr->length) * sizeof(void *));
+ }
+ if (arr->length <= idx)
+ arr->length = idx + 1;
+ return 0;
}
-int
-array_list_add(struct array_list *arr, void *data)
+int array_list_add(struct array_list *arr, void *data)
{
- return array_list_put_idx(arr, arr->length, data);
+ /* Repeat some of array_list_put_idx() so we can skip several
+ checks that we know are unnecessary when appending at the end
+ */
+ size_t idx = arr->length;
+ if (idx > SIZE_T_MAX - 1)
+ return -1;
+ if (array_list_expand_internal(arr, idx + 1))
+ return -1;
+ arr->array[idx] = data;
+ arr->length++;
+ return 0;
}
-void
-array_list_sort(struct array_list *arr, int(*sort_fn)(const void *, const void *))
+void array_list_sort(struct array_list *arr, int (*compar)(const void *, const void *))
{
- qsort(arr->array, arr->length, sizeof(arr->array[0]), sort_fn);
+ qsort(arr->array, arr->length, sizeof(arr->array[0]), compar);
}
-void* array_list_bsearch(const void **key, struct array_list *arr,
- int (*sort_fn)(const void *, const void *))
+void *array_list_bsearch(const void **key, struct array_list *arr,
+ int (*compar)(const void *, const void *))
{
- return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]),
- sort_fn);
+ return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]), compar);
}
-size_t
-array_list_length(struct array_list *arr)
+size_t array_list_length(struct array_list *arr)
{
- return arr->length;
+ return arr->length;
}
-int
-array_list_del_idx( struct array_list *arr, size_t idx, size_t count )
+int array_list_del_idx(struct array_list *arr, size_t idx, size_t count)
{
size_t i, stop;
+ /* Avoid overflow in calculation with large indices. */
+ if (idx > SIZE_T_MAX - count)
+ return -1;
stop = idx + count;
- if ( idx >= arr->length || stop > arr->length ) return -1;
- for ( i = idx; i < stop; ++i ) {
- if ( arr->array[i] ) arr->free_fn( arr->array[i] );
+ if (idx >= arr->length || stop > arr->length)
+ return -1;
+ for (i = idx; i < stop; ++i)
+ {
+ // Because put_idx can skip entries, we need to check if
+ // there's actually anything in each slot we're erasing.
+ if (arr->array[i])
+ arr->free_fn(arr->array[i]);
}
- memmove( arr->array + idx, arr->array + stop, (arr->length - stop) * sizeof(void*) );
+ memmove(arr->array + idx, arr->array + stop, (arr->length - stop) * sizeof(void *));
arr->length -= count;
return 0;
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/arraylist.h thunderbird-91.8.1+build1/comm/third_party/json-c/arraylist.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/arraylist.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/arraylist.h 2022-04-15 07:49:22.000000000 +0000
@@ -22,46 +22,64 @@
extern "C" {
#endif
+#include
+
#define ARRAY_LIST_DEFAULT_SIZE 32
-typedef void (array_list_free_fn) (void *data);
+typedef void(array_list_free_fn)(void *data);
struct array_list
{
- void **array;
- size_t length;
- size_t size;
- array_list_free_fn *free_fn;
+ void **array;
+ size_t length;
+ size_t size;
+ array_list_free_fn *free_fn;
};
typedef struct array_list array_list;
-extern struct array_list*
-array_list_new(array_list_free_fn *free_fn);
-
-extern void
-array_list_free(struct array_list *al);
-
-extern void*
-array_list_get_idx(struct array_list *al, size_t i);
-
-extern int
-array_list_put_idx(struct array_list *al, size_t i, void *data);
-
-extern int
-array_list_add(struct array_list *al, void *data);
-
-extern size_t
-array_list_length(struct array_list *al);
-
-extern void
-array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *));
-
-extern void* array_list_bsearch(const void **key,
- struct array_list *arr,
- int (*sort_fn)(const void *, const void *));
-
-extern int
-array_list_del_idx(struct array_list *arr, size_t idx, size_t count);
+/**
+ * Allocate an array_list of the default size (32).
+ * @deprecated Use array_list_new2() instead.
+ */
+extern struct array_list *array_list_new(array_list_free_fn *free_fn);
+
+/**
+ * Allocate an array_list of the desired size.
+ *
+ * If possible, the size should be chosen to closely match
+ * the actual number of elements expected to be used.
+ * If the exact size is unknown, there are tradeoffs to be made:
+ * - too small - the array_list code will need to call realloc() more
+ * often (which might incur an additional memory copy).
+ * - too large - will waste memory, but that can be mitigated
+ * by calling array_list_shrink() once the final size is known.
+ *
+ * @see array_list_shrink
+ */
+extern struct array_list *array_list_new2(array_list_free_fn *free_fn, int initial_size);
+
+extern void array_list_free(struct array_list *al);
+
+extern void *array_list_get_idx(struct array_list *al, size_t i);
+
+extern int array_list_put_idx(struct array_list *al, size_t i, void *data);
+
+extern int array_list_add(struct array_list *al, void *data);
+
+extern size_t array_list_length(struct array_list *al);
+
+extern void array_list_sort(struct array_list *arr, int (*compar)(const void *, const void *));
+
+extern void *array_list_bsearch(const void **key, struct array_list *arr,
+ int (*compar)(const void *, const void *));
+
+extern int array_list_del_idx(struct array_list *arr, size_t idx, size_t count);
+
+/**
+ * Shrink the array list to just enough to fit the number of elements in it,
+ * plus empty_slots.
+ */
+extern int array_list_shrink(struct array_list *arr, size_t empty_slots);
#ifdef __cplusplus
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/AUTHORS thunderbird-91.8.1+build1/comm/third_party/json-c/AUTHORS
--- thunderbird-91.7.0+build2/comm/third_party/json-c/AUTHORS 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/AUTHORS 2022-04-15 07:49:21.000000000 +0000
@@ -1,5 +1,30 @@
-Michael Clark
-Jehiah Czebotar
-Eric Haszlakiewicz
+Alexander Dahl
+andy5995
+Björn Esser
+changyong guo
+chenguoping
+Christopher Head
+Chris Wolfe
C. Watford (christopher.watford@gmail.com)
-
+Darjan Krijan
+Eric Hawicz
+grdowns
+Ivan Romanov
+Jaap Keuter
+janczer
+Jehan
+Jehiah Czebotar
+Jonathan Wiens
+Jose Bollo
+Keith Holman
+Liang, Gao
+max
+Michael Clark
+myd7349
+Pierce Lopez
+Po-Chuan Hsieh
+Ramiro Polla
+Rikard Falkeborn
+Robert
+Rubasri Kalidas
+Unmanned Player <36690541+unmanned-player@users.noreply.github.com>
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/bits.h thunderbird-91.8.1+build1/comm/third_party/json-c/bits.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/bits.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/bits.h 1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-/**
- * @file
- * @brief Do not use, only contains deprecated defines.
- * @deprecated Use json_util.h instead.
- *
- * $Id: bits.h,v 1.10 2006/01/30 23:07:57 mclark Exp $
- *
- * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
- * Michael Clark
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See COPYING for details.
- *
- */
-
-#ifndef _bits_h_
-#define _bits_h_
-
-/**
- * @deprecated
- */
-#define hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
-/**
- * @deprecated
- */
-#define error_ptr(error) ((void*)error)
-/**
- * @deprecated
- */
-#define error_description(error) (json_tokener_get_error(error))
-/**
- * @deprecated
- */
-#define is_error(ptr) (ptr == NULL)
-
-#endif
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/ChangeLog thunderbird-91.8.1+build1/comm/third_party/json-c/ChangeLog
--- thunderbird-91.7.0+build2/comm/third_party/json-c/ChangeLog 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/ChangeLog 2022-04-15 07:49:21.000000000 +0000
@@ -1,8 +1,154 @@
+Next Release 0.15
+=====================
+
+Deprecated and removed features:
+--------------------------------
+* Deprecate `array_list_new()` in favor of `array_list_new2()`
+* Remove the THIS_FUNCTION_IS_DEPRECATED define.
+* Remove config.h.win32
+
+New features
+------------
+* Add a `JSON_TOKENER_ALLOW_TRAILING_CHARS` flag to allow multiple objects
+ to be parsed even when `JSON_TOKENER_STRICT` is set.
+* Add `json_object_new_array_ext(int)` and `array_list_new_2(int)` to allow
+ arrays to be allocated with the exact size needed, when known.
+* Add `json_object_array_shrink()` (and `array_list_shrink()`) and use it in
+ json_tokener to minimize the amount of memory used.
+* Add a json_parse binary, for use in testing changes (not installed, but
+ available in the apps directory).
+
+Build changes
+-------------
+* #639/#621 - Add symbol versions to all exported symbols
+* #508/#634 - Always enable -fPIC to allow use of the json-c static library in
+ other libraries
+* Build both static and shared libraries at the same time.
+* #626 - Restore compatibility with cmake 2.8
+* #471 - Always create directories with mode 0755, regardless of umask.
+* #606/#604 - Improve support for OSes like AIX and IBM i, as well as for
+ MINGW32 and old versions of MSVC
+* #451/#617 - Add a DISABLE_THREAD_LOCAL_STORAGE cmake option to disable
+ the use of thread-local storage.
+
+Significant changes and bug fixes
+---------------------------------
+* Split the internal json_object structure into several sub-types, one for
+ each json_type (json_object_object, json_object_string, etc...).
+ This improves memory usage and speed, with the benchmark under
+ bench/ report 5.8% faster test time and 6%(max RSS)-12%(peak heap)
+ less memory usage.
+ Memory used just for json_object structures decreased 27%, so use cases
+ with fewer arrays and/or strings would benefit more.
+* Minimize memory usage in array handling in json_tokener by shrinking
+ arrays to the exact number of elements parsed. On bench/ benchmark:
+ 9% faster test time, 39%(max RSS)-50%(peak heap) less memory usage.
+ Add json_object_array_shrink() and array_list_shrink() functions.
+* #616 - Parsing of surrogate pairs in unicode escapes now properly handles
+ incremental parsing.
+* Fix incremental parsing of numbers, especially those with exponents, e.g.
+ so parsing "[0", "e+", "-]" now properly returns an error.
+ Strict mode now rejects missing exponents ("0e").
+* Successfully return number objects at the top level even when they are
+ followed by a "-", "." or "e". This makes parsing things like "123-45"
+ behave consistently with things like "123xyz".
+
+Other changes
+-------------
+* #589 - Detect broken RDRAND during initialization; also, fix segfault
+ in the CPUID check.
+* #592 - Fix integer overflows to prevert out of bounds write on large input.
+* Protect against division by zero in linkhash, when creaed with zero size.
+* #602 - Fix json_parse_uint64() internal error checking, leaving the retval
+ untouched in more failure cases.
+* #614 - Prevent truncation when custom double formatters insert extra \0's
+
+
+***
+
+0.14 (up to commit 9ed00a6, 2020/04/14)
+=========================================
+
+Deprecated and removed features:
+--------------------------------
+* bits.h has been removed
+* lh_abort() has been removed
+* lh_table_lookup() has been removed, use lh_table_lookup_ex() instead.
+* Remove TRUE and FALSE defines, use 1 and 0 instead.
+
+Build changes:
+--------------
+## Deprecated and removed features:
+* bits.h has been removed
+* lh_abort() has been removed
+* lh_table_lookup() has been removed, use lh_table_lookup_ex() instead.
+* Remove TRUE and FALSE defines, use 1 and 0 instead.
+* autoconf support, including autogen.sh, has been removed. See details about cmake, below.
+* With the addition of json_tokener_get_parse_end(), access to internal fields of json_tokener, as well as use of many other symbols and types in json_tokener.h, is deprecated now.
+* The use of Android.configure.mk to build for Android no longer works, and it is unknown how (or if) the new cmake-based build machinery can be used.
+ * Reports of success, or pull requests to correct issues are welcome.
+
+## Notable improvements and new features
+
+### Builds and documentation
+* Build machinery has been switched to CMake. See README.md for details about how to build.
+ * TL;DR: `mkdir build ; cd build ; cmake -DCMAKE_INSTALL_PREFIX=/some/path ../json-c ; make all test install`
+ * To ease the transition, there is a `cmake-configure` wrapper that emulates the old autoconf-based configure script.
+ * This has enabled improvements to the build on Windows system; also all public functions have been fixed to be properly exported. For best results, use Visual Studio 2015 or newer.
+* The json-c style guide has been updated to specify the use of clang-format, and all code has been reformatted.
+ * Since many lines of code have trivial changes now, when using git blame, be sure to specify -w
+* Numerous improvements have been made to the documentation including function effects on refcounts, when passing a NULL is safe, and so on.
+
+### json_tokener changes
+* Added a json_tokener_get_parse_end() function to replace direct access of tok->char_offset.
+ * The char_offset field, and the rest of the json_tokener structure remain exposed for now, but expect a future release to hide it like is done with json_object_private.h
+* json_tokener_parse_ex() now accepts a new JSON_TOKENER_VALIDATE_UTF8 flag to validate that input is UTF8.
+ * If validation fails, json_tokener_get_error(tok) will return json_tokener_error_parse_utf8_string (see enum json_tokener_error).
+
+### Other changes and additions
+* Add support for unsigned 64-bit integers, uint64_t, to gain one extra bit of magnitude for positive ints.
+ * json_tokener will now parse values up to UINT64_MAX (18446744073709551615)
+ * Existing methods returning int32_t or int64_t will cap out-of-range values at INT32_MAX or INT64_MAX, preserving existing behavior.
+ * The implementation includes the possibility of easily extending this to larger sizes in the future.
+* A total of 7 new functions were added:
+ * json_object_get_uint64 ( struct json_object const* jso )
+ * json_object_new_uint64 ( uint64_t i )
+ * json_object_set_uint64 ( struct json_object* jso, uint64_t new_value )
+ * json_parse_uint64 ( char const* buf, uint64_t* retval )
+ * See description of uint64 support, above.
+ * json_tokener_get_parse_end ( struct json_tokener* tok )
+ * See details under "json_tokener changes", above.
+ * json_object_from_fd_ex ( int fd, int in_depth )
+ * Allows the max nesting depth to be specified.
+ * json_object_new_null ( )
+ * Simply returns NULL. Its use is not recommended.
+* The size of struct json_object has decreased from 96 bytes to 88 bytes.
+
+### Testing
+* Many updates were made to test cases, increasing code coverage.
+* There is now a quick way (JSONC_TEST_TRACE=1) to turn on shell tracing in tests.
+* To run tests, use `make test`; the old "check" target no longer exists.
+
+## Significant bug fixes
+For the full list of issues and pull requests since the previous release, please see issues_closed_for_0.14.md
+
+* [Issue #389](https://github.com/json-c/json-c/issues/389): Add an assert to explicitly crash when _ref_count is corrupted, instead of a later "double free" error.
+* [Issue #407](https://github.com/json-c/json-c/issues/407): fix incorrect casts in calls to ctype functions (isdigit and isspace) so we don't crash when asserts are enabled on certain platforms and characters > 128 are parsed.
+* [Issue #418](https://github.com/json-c/json-c/issues/418): Fix docs for json_util_from_fd and json_util_from_file to say that they return NULL on failures.
+* [Issue #422](https://github.com/json-c/json-c/issues/422): json_object.c:set errno in json_object_get_double() when called on a json_type_string object with bad content.
+* [Issue #453](https://github.com/json-c/json-c/issues/453): Fixed misalignment in JSON serialization when JSON_C_TO_STRING_SPACED and JSON_C_TO_STRING_PRETTY are used together.
+* [Issue #463](https://github.com/json-c/json-c/issues/463): fix newlocale() call to use LC_NUMERIC_MASK instead of LC_NUMERIC, and remove incorrect comment.
+* [Issue #486](https://github.com/json-c/json-c/issues/486): append a missing ".0" to negative double values to ensure they are serialized as floating point numbers.
+* [Issue #488](https://github.com/json-c/json-c/issues/488): use JSON_EXPORT on functions so they are properly exported on Windows.
+* [Issue #539](https://github.com/json-c/json-c/issues/539): use an internal-only serializer function in json_object_new_double_s() to avoid potential conflicts with user code that uses the json_object_userdata_to_json_string serializer.
+
+***
+
0.13.1 (up to commit 0f814e5, 2018/03/04)
=========================================
-* Bump the major version of the .so library generated up to 4.0 to avoid
+* Bump the major version of the .so library generated up to 4.0 to avoid
conflicts because some downstream packagers of json-c had already done
their own bump to ".so.3" for a much older 0.12 release.
* Add const size_t json_c_object_sizeof()
@@ -12,6 +158,7 @@
* Issue #396: fix build for certain uClibc based systems.
* Add a top level fuzz directory for fuzzers run by OSS-Fuzz
+
0.13 (up to commit 5dae561, 2017/11/29)
=================================
@@ -26,7 +173,7 @@
Deprecated and removed features:
--------------------------------
* All internal use of bits.h has been eliminated. The file will be removed.
- Do not use: hexdigit(), error_ptr(), error_descrition() and it_error()
+ Do not use: hexdigit(), error_ptr(), error_descrition() and it_error()
* lh_abort() is deprecated. It will be removed.
Behavior changes:
@@ -169,11 +316,11 @@
* Make the json_tokener_errors array local. It has been deprecated for
a while, and json_tokener_error_desc() should be used instead.
- * change the floating point output format to %.17g so values with
+ * change the floating point output format to %.17g so values with
more than 6 digits show up in the output.
* Remove the old libjson.so name compatibility support. The library is
- only created as libjson-c.so now and headers are only installed
+ only created as libjson-c.so now and headers are only installed
into the ${prefix}/json-c directory.
* When supported by the linker, add the -Bsymbolic-functions flag.
@@ -239,7 +386,7 @@
* Allow json_tokener_parse_ex() to be re-used to parse multiple object.
Also, fix some parsing issues with capitalized hexadecimal numbers and
number in E notation.
- * Add json_tokener_get_error() and json_tokener_error_desc() to better
+ * Add json_tokener_get_error() and json_tokener_error_desc() to better
encapsulate the process of retrieving errors while parsing.
* Various improvements to the documentation of many functions.
* Add new json_object_array_sort() function.
@@ -286,7 +433,7 @@
Brent Miller, bdmiller at yahoo dash inc dot com
* Disable REFCOUNT_DEBUG by default in json_object.c
* Don't use this as a variable, so we can compile with a C++ compiler
- * Add casts from void* to type of assignment when using malloc
+ * Add casts from void* to type of assignment when using malloc
* Add #ifdef __cplusplus guards to all of the headers
* Add typedefs for json_object, json_tokener, array_list, printbuf, lh_table
Michael Clark,
@@ -322,7 +469,7 @@
0.6
===
* Fix bug in escaping of control characters
- Johan Bjrklund, johbjo09 at kth dot se
+ Johan Björklund, johbjo09 at kth dot se
* Remove include "config.h" from headers (should only
be included from .c files)
Michael Clark
@@ -370,13 +517,13 @@
Added a Win32/Win64 compliant implementation of strndup
* json_util.c - C. Watford (christopher.watford@gmail.com)
Added cast and mask to suffice size_t v. unsigned int conversion
- correctness
+ correctness
* json_tokener.c - sign reversal issue on error info for nested object parse
- spotted by Johan Bjrklund (johbjo09 at kth.se)
+ spotted by Johan Björklund (johbjo09 at kth.se)
* json_object.c - escape " in json_escape_str
* Change to automake and libtool to build shared and static library
Michael Clark
-
+
0.1
===
* initial release
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/config.h.in thunderbird-91.8.1+build1/comm/third_party/json-c/config.h.in
--- thunderbird-91.7.0+build2/comm/third_party/json-c/config.h.in 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/config.h.in 2022-04-15 07:49:21.000000000 +0000
@@ -1,46 +1,20 @@
-/* config.h.in. Generated from configure.ac by autoheader. */
+/* config.h.in. Modified for moz.build from cmake/config.h.in. */
/* Enable RDRAND Hardware RNG Hash Seed */
#undef ENABLE_RDRAND
+/* Override json_c_get_random_seed() with custom code */
+#undef OVERRIDE_GET_RANDOM_SEED
+
/* Enable partial threading support */
#undef ENABLE_THREADING
/* Define if .gnu.warning accepts long strings. */
#undef HAS_GNU_WARNING_LONG
-/* Has atomic builtins */
-#undef HAVE_ATOMIC_BUILTINS
-
-/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you
- don't. */
-#undef HAVE_DECL_INFINITY
-
-/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
- */
-#undef HAVE_DECL_ISINF
-
-/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
- */
-#undef HAVE_DECL_ISNAN
-
-/* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */
-#undef HAVE_DECL_NAN
-
-/* Define to 1 if you have the declaration of `_finite', and to 0 if you
- don't. */
-#undef HAVE_DECL__FINITE
-
-/* Define to 1 if you have the declaration of `_isnan', and to 0 if you don't.
- */
-#undef HAVE_DECL__ISNAN
-
/* Define to 1 if you have the header file. */
#undef HAVE_DLFCN_H
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-#undef HAVE_DOPRNT
-
/* Define to 1 if you have the header file. */
#undef HAVE_ENDIAN_H
@@ -59,18 +33,6 @@
/* Define to 1 if you have the header file. */
#undef HAVE_MEMORY_H
-/* Define to 1 if you have the `open' function. */
-#undef HAVE_OPEN
-
-/* Define to 1 if you have the `realloc' function. */
-#undef HAVE_REALLOC
-
-/* Define to 1 if you have the `setlocale' function. */
-#undef HAVE_SETLOCALE
-
-/* Define to 1 if you have the `snprintf' function. */
-#undef HAVE_SNPRINTF
-
/* Define to 1 if you have the header file. */
#undef HAVE_STDARG_H
@@ -80,24 +42,12 @@
/* Define to 1 if you have the header file. */
#undef HAVE_STDLIB_H
-/* Define to 1 if you have the `strcasecmp' function. */
-#undef HAVE_STRCASECMP
-
-/* Define to 1 if you have the `strdup' function. */
-#undef HAVE_STRDUP
-
-/* Define to 1 if you have the `strerror' function. */
-#undef HAVE_STRERROR
-
/* Define to 1 if you have the header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the header file. */
#undef HAVE_STRING_H
-/* Define to 1 if you have the `strncasecmp' function. */
-#undef HAVE_STRNCASECMP
-
/* Define to 1 if you have the header file. */
#undef HAVE_SYSLOG_H
@@ -107,6 +57,9 @@
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_PARAM_H
+/* Define to 1 if you have the header file. */
+#undef HAVE_SYS_RESOURCE_H
+
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_STAT_H
@@ -116,6 +69,63 @@
/* Define to 1 if you have the header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the header file. */
+#undef HAVE_XLOCALE_H
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Has atomic builtins */
+#undef HAVE_ATOMIC_BUILTINS
+
+/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you
+ don't. */
+#undef HAVE_DECL_INFINITY
+
+/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
+ */
+#undef HAVE_DECL_ISINF
+
+/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
+ */
+#undef HAVE_DECL_ISNAN
+
+/* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */
+#undef HAVE_DECL_NAN
+
+/* Define to 1 if you have the declaration of `_finite', and to 0 if you
+ don't. */
+#undef HAVE_DECL__FINITE
+
+/* Define to 1 if you have the declaration of `_isnan', and to 0 if you don't.
+ */
+#undef HAVE_DECL__ISNAN
+
+/* Define to 1 if you have the `open' function. */
+#undef HAVE_OPEN
+
+/* Define to 1 if you have the `realloc' function. */
+#undef HAVE_REALLOC
+
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
/* Define to 1 if you have the `uselocale' function. */
#undef HAVE_USELOCALE
@@ -131,8 +141,8 @@
/* Define to 1 if you have the `vsyslog' function. */
#undef HAVE_VSYSLOG
-/* Define to 1 if you have the header file. */
-#undef HAVE_XLOCALE_H
+/* Define if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
/* Have __thread */
#undef HAVE___THREAD
@@ -140,10 +150,6 @@
/* Public define for json_inttypes.h */
#undef JSON_C_HAVE_INTTYPES_H
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#undef LT_OBJDIR
-
/* Name of package */
#undef PACKAGE
@@ -180,6 +186,9 @@
/* The number of bytes in type size_t */
#undef SIZEOF_SIZE_T
+/* The number of bytes in type ssize_t */
+#undef SIZEOF_SSIZE_T
+
/* Specifier for __thread */
#undef SPEC___THREAD
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/config.h.win32 thunderbird-91.8.1+build1/comm/third_party/json-c/config.h.win32
--- thunderbird-91.7.0+build2/comm/third_party/json-c/config.h.win32 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/config.h.win32 1970-01-01 00:00:00.000000000 +0000
@@ -1,205 +0,0 @@
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Enable RDRANR Hardware RNG Hash Seed */
-#undef ENABLE_RDRAND
-
-/* Define if .gnu.warning accepts long strings. */
-#undef HAS_GNU_WARNING_LONG
-
-/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you
- don't. */
-#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__)
-#define HAVE_DECL_INFINITY 1
-#endif
-
-/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
- */
-#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__)
-#define HAVE_DECL_ISINF 1
-#endif
-
-/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
- */
-#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__)
-#define HAVE_DECL_ISNAN 1
-#endif
-
-/* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */
-#if (defined(_MSC_VER) && _MSC_VER >= 1800) || defined(__MINGW32__)
-#define HAVE_DECL_NAN 1
-#endif
-
-/* Define to 1 if you have the declaration of `_finite', and to 0 if you
- don't. */
-#define HAVE_DECL__FINITE 1
-
-/* Define to 1 if you have the declaration of `_isnan', and to 0 if you don't.
- */
-#define HAVE_DECL__ISNAN 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
-#define HAVE_DOPRNT 1
-
-/* Define to 1 if you have the header file. */
-#undef HAVE_ENDIAN_H
-
-/* Define to 1 if you have the header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_LOCALE_H 1
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
- to 0 otherwise. */
-#define HAVE_MALLOC 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `open' function. */
-#define HAVE_OPEN 1
-
-/* Define to 1 if your system has a GNU libc compatible `realloc' function,
- and to 0 otherwise. */
-#define HAVE_REALLOC 1
-
-/* Define to 1 if you have the `setlocale' function. */
-#define HAVE_SETLOCALE 1
-
-/* Define to 1 if you have the `snprintf' function. */
-#if defined(__MINGW32__)
-#define HAVE_SNPRINTF 1
-#else
-#undef HAVE_SNPRINTF
-#endif
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STDARG_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#define HAVE_STRCASECMP 1
-
-/* Define to 1 if you have the `strdup' function. */
-#define HAVE_STRDUP 0
-
-/* Define to 1 if you have the `strerror' function. */
-#define HAVE_STRERROR 1
-
-/* Define to 1 if you have the header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strncasecmp' function. */
-#if defined(__MINGW32__)
-#define HAVE_STRNCASECMP 1
-#else
-#undef HAVE_STRNCASECMP
-#endif
-
-#cmakedefine HAVE_STRTOLL
-#cmakedefine strtoll @cmake_strtoll@
-
-/* Define to 1 if you have the header file. */
-#undef HAVE_SYSLOG_H
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_CDEFS_H 1
-
-/* Define to 1 if you have the header file. */
-#if defined(__MINGW32__)
-#define HAVE_SYS_PARAM_H 1
-#else
-#undef HAVE_SYS_PARAM_H
-#endif
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the header file. */
-#if defined(__MINGW32__)
-#define HAVE_UNISTD_H 1
-#else
-#undef HAVE_UNISTD_H
-#endif
-
-/* Define to 1 if you have the `vasprintf' function. */
-#if defined(__MINGW32__)
-#define HAVE_VASPRINTF 1
-#else
-#undef HAVE_VASPRINTF
-#endif
-
-/* Define to 1 if you have the `vprintf' function. */
-#define HAVE_VPRINTF 1
-
-/* Define to 1 if you have the `vsnprintf' function. */
-#define HAVE_VSNPRINTF 1
-
-/* Define to 1 if you have the `vsyslog' function. */
-#undef HAVE_VSYSLOG
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#undef LT_OBJDIR
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
-
-/* Name of package */
-#define PACKAGE "json-c"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "json-c@googlegroups.com"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "JSON C Library"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "JSON C Library 0.13.1"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "json-c"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL "https://github.com/json-c/json-c"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.13.1"
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "0.13.1"
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to rpl_malloc if the replacement function should be used. */
-/* #undef malloc */
-
-/* Define to rpl_realloc if the replacement function should be used. */
-/* #undef realloc */
-
-/* Define to `unsigned int' if does not define. */
-/* #undef size_t */
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/debug.c thunderbird-91.8.1+build1/comm/third_party/json-c/debug.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/debug.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/debug.c 2022-04-15 07:49:21.000000000 +0000
@@ -11,17 +11,17 @@
#include "config.h"
+#include
#include
#include
#include
-#include
#if HAVE_SYSLOG_H
-# include
+#include
#endif /* HAVE_SYSLOG_H */
#if HAVE_UNISTD_H
-# include
+#include
#endif /* HAVE_UNISTD_H */
#if HAVE_SYS_PARAM_H
@@ -33,51 +33,64 @@
static int _syslog = 0;
static int _debug = 0;
-void mc_set_debug(int debug) { _debug = debug; }
-int mc_get_debug(void) { return _debug; }
+void mc_set_debug(int debug)
+{
+ _debug = debug;
+}
+int mc_get_debug(void)
+{
+ return _debug;
+}
extern void mc_set_syslog(int syslog)
{
- _syslog = syslog;
+ _syslog = syslog;
}
void mc_debug(const char *msg, ...)
{
- va_list ap;
- if(_debug) {
- va_start(ap, msg);
+ va_list ap;
+ if (_debug)
+ {
+ va_start(ap, msg);
#if HAVE_VSYSLOG
- if(_syslog) {
- vsyslog(LOG_DEBUG, msg, ap);
- } else
+ if (_syslog)
+ {
+ vsyslog(LOG_DEBUG, msg, ap);
+ }
+ else
#endif
- vprintf(msg, ap);
- va_end(ap);
- }
+ vprintf(msg, ap);
+ va_end(ap);
+ }
}
void mc_error(const char *msg, ...)
{
- va_list ap;
- va_start(ap, msg);
+ va_list ap;
+ va_start(ap, msg);
#if HAVE_VSYSLOG
- if(_syslog) {
+ if (_syslog)
+ {
vsyslog(LOG_ERR, msg, ap);
- } else
+ }
+ else
#endif
vfprintf(stderr, msg, ap);
- va_end(ap);
+ va_end(ap);
}
void mc_info(const char *msg, ...)
{
- va_list ap;
- va_start(ap, msg);
+ va_list ap;
+ va_start(ap, msg);
#if HAVE_VSYSLOG
- if(_syslog) {
+ if (_syslog)
+ {
vsyslog(LOG_INFO, msg, ap);
- } else
+ }
+ else
#endif
vfprintf(stderr, msg, ap);
- va_end(ap);
+ va_end(ap);
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/debug.h thunderbird-91.8.1+build1/comm/third_party/json-c/debug.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/debug.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/debug.h 2022-04-15 07:49:21.000000000 +0000
@@ -23,14 +23,22 @@
extern "C" {
#endif
-extern void mc_set_debug(int debug);
-extern int mc_get_debug(void);
+#ifndef JSON_EXPORT
+#if defined(_MSC_VER)
+#define JSON_EXPORT __declspec(dllexport)
+#else
+#define JSON_EXPORT extern
+#endif
+#endif
+
+JSON_EXPORT void mc_set_debug(int debug);
+JSON_EXPORT int mc_get_debug(void);
-extern void mc_set_syslog(int syslog);
+JSON_EXPORT void mc_set_syslog(int syslog);
-extern void mc_debug(const char *msg, ...);
-extern void mc_error(const char *msg, ...);
-extern void mc_info(const char *msg, ...);
+JSON_EXPORT void mc_debug(const char *msg, ...);
+JSON_EXPORT void mc_error(const char *msg, ...);
+JSON_EXPORT void mc_info(const char *msg, ...);
#ifndef __STRING
#define __STRING(x) #x
@@ -38,17 +46,24 @@
#ifndef PARSER_BROKEN_FIXED
-#define JASSERT(cond) do {} while(0)
+#define JASSERT(cond) \
+ do \
+ { \
+ } while (0)
#else
-#define JASSERT(cond) do { \
- if (!(cond)) { \
- mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", __FILE__, __LINE__); \
- *(int *)0 = 1;\
- abort(); \
- }\
- } while(0)
+#define JASSERT(cond) \
+ do \
+ { \
+ if (!(cond)) \
+ { \
+ mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", \
+ __FILE__, __LINE__); \
+ *(int *)0 = 1; \
+ abort(); \
+ } \
+ } while (0)
#endif
@@ -61,11 +76,19 @@
#define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__)
#define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__)
#else
-#define MC_SET_DEBUG(x) if (0) mc_set_debug(x)
+#define MC_SET_DEBUG(x) \
+ if (0) \
+ mc_set_debug(x)
#define MC_GET_DEBUG() (0)
-#define MC_SET_SYSLOG(x) if (0) mc_set_syslog(x)
-#define MC_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__)
-#define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__)
+#define MC_SET_SYSLOG(x) \
+ if (0) \
+ mc_set_syslog(x)
+#define MC_DEBUG(x, ...) \
+ if (0) \
+ mc_debug(x, ##__VA_ARGS__)
+#define MC_INFO(x, ...) \
+ if (0) \
+ mc_info(x, ##__VA_ARGS__)
#endif
#ifdef __cplusplus
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/INSTALL thunderbird-91.8.1+build1/comm/third_party/json-c/INSTALL
--- thunderbird-91.7.0+build2/comm/third_party/json-c/INSTALL 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/INSTALL 2022-04-15 07:49:21.000000000 +0000
@@ -1,3 +1,2 @@
See README.md for installation instructions.
-
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/issues_closed_for_0.13.md thunderbird-91.8.1+build1/comm/third_party/json-c/issues_closed_for_0.13.md
--- thunderbird-91.7.0+build2/comm/third_party/json-c/issues_closed_for_0.13.md 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/issues_closed_for_0.13.md 2022-04-15 07:49:21.000000000 +0000
@@ -1,267 +1,270 @@
This list was created with:
+```
curl https://api.github.com/search/issues?q="repo%3Ajson-c%2Fjson-c+closed%3A>2014-04-10+created%3A<2017-12-01&sort=created&order=asc&per_page=400&page=1" > issues1.out
curl https://api.github.com/search/issues?q="repo%3Ajson-c%2Fjson-c+closed%3A>2014-04-10+created%3A<2017-12-01&sort=created&order=asc&per_page=400&page=2" > issues2.out
curl https://api.github.com/search/issues?q="repo%3Ajson-c%2Fjson-c+closed%3A>2014-04-10+created%3A<2017-12-01&sort=created&order=asc&per_page=400&page=3" > issues3.out
jq -r '.items[] | "[" + .title + "](" + .url + ")" | tostring' issues?.out > issues.md
+sed -e's,^\[ *\(.*\)\](https://api.github.com/.*/\([0-9].*\)),[Issue #\2](https://github.com/json-c/json-c/issues/\2) - \1,' -i issues.md
#... manual editing ...
+```
----
Issues and Pull Requests closed for the 0.13 release
(since commit f84d9c, the 0.12 branch point, 2014-04-10)
-[Make json_object_object_add() indicate success or failure, test fix](https://api.github.com/repos/json-c/json-c/issues/61)
-[Build fixes (make dist and make distcheck)](https://api.github.com/repos/json-c/json-c/issues/113)
-[Fixing build](https://api.github.com/repos/json-c/json-c/issues/124)
-[Fix compile error(variable size set but not used) on g++4.6](https://api.github.com/repos/json-c/json-c/issues/125)
-[Removed unused size variable.](https://api.github.com/repos/json-c/json-c/issues/126)
-[remove unused `size` variable](https://api.github.com/repos/json-c/json-c/issues/127)
-[Remove unused variable from json_tokenizer.c](https://api.github.com/repos/json-c/json-c/issues/128)
-[Failed to compile under Ubuntu 13.10 32bit](https://api.github.com/repos/json-c/json-c/issues/130)
-[undefined symbol: __sync_val_compare_and_swap_4 ](https://api.github.com/repos/json-c/json-c/issues/131)
-[Remove unused variable 'size'](https://api.github.com/repos/json-c/json-c/issues/132)
-[Update and rename README to README.md](https://api.github.com/repos/json-c/json-c/issues/133)
-[Must remove variable size...](https://api.github.com/repos/json-c/json-c/issues/134)
-[bits.h uses removed json_tokener_errors\[error\]](https://api.github.com/repos/json-c/json-c/issues/135)
-[Error when running make check](https://api.github.com/repos/json-c/json-c/issues/136)
-[config.h.in should not be in git](https://api.github.com/repos/json-c/json-c/issues/137)
-[Can't build on RHEL 6.5 due to dependency on automake-1.14](https://api.github.com/repos/json-c/json-c/issues/138)
-[Code bug in random_test.c evaluating same expression twice ](https://api.github.com/repos/json-c/json-c/issues/140)
-[Removed duplicate check in random_seed test - bug #140](https://api.github.com/repos/json-c/json-c/issues/141)
-[Please undeprecate json_object_object_get](https://api.github.com/repos/json-c/json-c/issues/142)
-[Introduce json_object_from_fd](https://api.github.com/repos/json-c/json-c/issues/144)
-[Handle % character properly](https://api.github.com/repos/json-c/json-c/issues/145)
-[TAGS rename](https://api.github.com/repos/json-c/json-c/issues/146)
-[Bump the soname](https://api.github.com/repos/json-c/json-c/issues/148)
-[SONAME bump](https://api.github.com/repos/json-c/json-c/issues/149)
-[Fix build using MinGW.](https://api.github.com/repos/json-c/json-c/issues/150)
-[Remove json_type enum trailing comma](https://api.github.com/repos/json-c/json-c/issues/151)
-[error while compiling json-c library version 0.11](https://api.github.com/repos/json-c/json-c/issues/152)
-[improve doc for json_object_to_json_string()](https://api.github.com/repos/json-c/json-c/issues/153)
-[double precision](https://api.github.com/repos/json-c/json-c/issues/154)
-[add bsearch for arrays](https://api.github.com/repos/json-c/json-c/issues/155)
-[Remove trailing whitespaces](https://api.github.com/repos/json-c/json-c/issues/156)
-[JSON-C shall not exit on calloc fail.](https://api.github.com/repos/json-c/json-c/issues/157)
-[while using json-c 0.11, I am facing strange crash issue in json_object_put.](https://api.github.com/repos/json-c/json-c/issues/158)
-[json_tokener.c compile error](https://api.github.com/repos/json-c/json-c/issues/159)
-[missing header file on windows??](https://api.github.com/repos/json-c/json-c/issues/160)
-[Is there a way to append to file?](https://api.github.com/repos/json-c/json-c/issues/161)
-[json_util: add directory check for POSIX distros](https://api.github.com/repos/json-c/json-c/issues/162)
-[Fix Win32 build problems](https://api.github.com/repos/json-c/json-c/issues/163)
-[made it compile and link on Widnows (as static library)](https://api.github.com/repos/json-c/json-c/issues/164)
-[json_object_to_json_string_ext length](https://api.github.com/repos/json-c/json-c/issues/165)
-[Can't build on Windows with Visual Studio 2010](https://api.github.com/repos/json-c/json-c/issues/167)
-[Tightening the number parsing algorithm](https://api.github.com/repos/json-c/json-c/issues/168)
-[Doesn't compile on ubuntu 14.04, 64bit](https://api.github.com/repos/json-c/json-c/issues/169)
-[Generated files in repository](https://api.github.com/repos/json-c/json-c/issues/170)
-[Update configuration for VS2010 and win64](https://api.github.com/repos/json-c/json-c/issues/171)
-[Adding support for parsing octal numbers](https://api.github.com/repos/json-c/json-c/issues/172)
-[json_parse_int64 doesn't work correctly at illumos](https://api.github.com/repos/json-c/json-c/issues/173)
-[Adding JSON_C_TO_STRING_PRETTY_TAB flag](https://api.github.com/repos/json-c/json-c/issues/174)
-[make check fails 4 tests with overflows when built with ASAN](https://api.github.com/repos/json-c/json-c/issues/175)
-[Possible to delete an array element at a given idx ?](https://api.github.com/repos/json-c/json-c/issues/176)
-[Fix compiler warnings](https://api.github.com/repos/json-c/json-c/issues/177)
-[Unable to compile on CentOS5](https://api.github.com/repos/json-c/json-c/issues/178)
-[Added array_list_del_idx and json_object_array_del_idx](https://api.github.com/repos/json-c/json-c/issues/179)
-[Enable silent build by default](https://api.github.com/repos/json-c/json-c/issues/180)
-[json_tokener_parse_ex accepts invalid JSON](https://api.github.com/repos/json-c/json-c/issues/181)
-[Link against libm when needed](https://api.github.com/repos/json-c/json-c/issues/182)
-[Apply compile warning fix to master branch](https://api.github.com/repos/json-c/json-c/issues/183)
-[Use only GCC-specific flags when compiling with GCC](https://api.github.com/repos/json-c/json-c/issues/184)
-[compile error](https://api.github.com/repos/json-c/json-c/issues/185)
-[Syntax error](https://api.github.com/repos/json-c/json-c/issues/186)
-[array_list_get_idx and negative indexes.](https://api.github.com/repos/json-c/json-c/issues/187)
-[json_object_object_foreach warnings](https://api.github.com/repos/json-c/json-c/issues/188)
-[noisy json_object_from_file: error opening file](https://api.github.com/repos/json-c/json-c/issues/189)
-[warning: initialization discards const qualifier from pointer target type \[enabled by default\]](https://api.github.com/repos/json-c/json-c/issues/190)
-[json_tokener_parse accepts invalid JSON {"key": "value" , }](https://api.github.com/repos/json-c/json-c/issues/192)
-[Make serialization format of doubles configurable](https://api.github.com/repos/json-c/json-c/issues/193)
-[Add utility function for comparing json_objects](https://api.github.com/repos/json-c/json-c/issues/194)
-[Call uselocale instead of setlocale](https://api.github.com/repos/json-c/json-c/issues/195)
-[Performance improvements](https://api.github.com/repos/json-c/json-c/issues/196)
-[Time for a new release?](https://api.github.com/repos/json-c/json-c/issues/197)
-[Fix possible memory leak and remove superfluous NULL checks before free()](https://api.github.com/repos/json-c/json-c/issues/198)
-[Fix build in Visual Studio](https://api.github.com/repos/json-c/json-c/issues/199)
-[Add build scripts for CI platforms](https://api.github.com/repos/json-c/json-c/issues/200)
-[disable forward-slash escaping?](https://api.github.com/repos/json-c/json-c/issues/201)
-[Array with objects support](https://api.github.com/repos/json-c/json-c/issues/202)
-[Add source position/coordinates to API](https://api.github.com/repos/json-c/json-c/issues/203)
-[json-c/json.h not found ](https://api.github.com/repos/json-c/json-c/issues/204)
-[json-c Compiled with Visual Studios](https://api.github.com/repos/json-c/json-c/issues/205)
-[what do i use in place of json_object_object_get?](https://api.github.com/repos/json-c/json-c/issues/206)
-[Add support for property pairs directly added to arrays](https://api.github.com/repos/json-c/json-c/issues/207)
-[Performance enhancements (mainly) to json_object_to_json_string()](https://api.github.com/repos/json-c/json-c/issues/208)
-[fix regression from 2d549662be832da838aa063da2efa78ee3b99668](https://api.github.com/repos/json-c/json-c/issues/209)
-[Use size_t for arrays](https://api.github.com/repos/json-c/json-c/issues/210)
-[Atomic updates for the refcount](https://api.github.com/repos/json-c/json-c/issues/211)
-[Refcount doesn't work between threads](https://api.github.com/repos/json-c/json-c/issues/212)
-[fix to compile with microsoft visual c++ 2010](https://api.github.com/repos/json-c/json-c/issues/213)
-[Some non-GNU systems support __sync_val_compare_and_swap](https://api.github.com/repos/json-c/json-c/issues/214)
-[Build json-c for window 64 bit.](https://api.github.com/repos/json-c/json-c/issues/215)
-[configure: check realloc with AC_CHECK_FUNCS() to fix cross-compilation.](https://api.github.com/repos/json-c/json-c/issues/216)
-[Checking for functions in float.h](https://api.github.com/repos/json-c/json-c/issues/217)
-[Use a macro to indicate C99 to the compiler](https://api.github.com/repos/json-c/json-c/issues/218)
-[Fix various potential null ptr deref and int32 overflows](https://api.github.com/repos/json-c/json-c/issues/219)
-[Add utility function for comparing json_objects](https://api.github.com/repos/json-c/json-c/issues/220)
-[JSON_C_TO_STRING_NOSLASHESCAPE works incorrectly](https://api.github.com/repos/json-c/json-c/issues/221)
-[Fix issue #221: JSON_C_TO_STRING_NOSLASHESCAPE works incorrectly](https://api.github.com/repos/json-c/json-c/issues/222)
-[Clarify json_object_get_string documentation of NULL handling & return](https://api.github.com/repos/json-c/json-c/issues/223)
-[json_tokener.c - all warnings being treated as errors](https://api.github.com/repos/json-c/json-c/issues/224)
-[Hi, will you support clib as a "registry"?](https://api.github.com/repos/json-c/json-c/issues/225)
-[Bump SOVERSION to 3](https://api.github.com/repos/json-c/json-c/issues/227)
-[avoid double slashes from json](https://api.github.com/repos/json-c/json-c/issues/228)
-[configure fails: checking size of size_t... configure: error: cannot determine a size for size_t](https://api.github.com/repos/json-c/json-c/issues/229)
-[Use stdint.h to check for size_t size](https://api.github.com/repos/json-c/json-c/issues/230)
-[Fix size_t size check for first-time builds](https://api.github.com/repos/json-c/json-c/issues/231)
-[tests/tests1: fix printf format for size_t arguments](https://api.github.com/repos/json-c/json-c/issues/232)
-[Include stddef.h in json_object.h](https://api.github.com/repos/json-c/json-c/issues/233)
-[Add public API to use userdata independently of custom serializer](https://api.github.com/repos/json-c/json-c/issues/234)
-[Undefined symbols Error for architecture x86_64 on Mac ](https://api.github.com/repos/json-c/json-c/issues/235)
-[Building a project which uses json-c with flag -Wcast-qual causes compilation errors](https://api.github.com/repos/json-c/json-c/issues/236)
-[handle escaped utf-8](https://api.github.com/repos/json-c/json-c/issues/237)
-[linkhash.c: optimised the table_free path](https://api.github.com/repos/json-c/json-c/issues/238)
-[initialize null terminator of new printbuf](https://api.github.com/repos/json-c/json-c/issues/239)
-[Compile error: Variable set but not used](https://api.github.com/repos/json-c/json-c/issues/240)
-[getting error in date string 19\/07\/2016, fixed for error 19/07/2016](https://api.github.com/repos/json-c/json-c/issues/241)
-[json_tokener_parse error](https://api.github.com/repos/json-c/json-c/issues/242)
-[Fix #165](https://api.github.com/repos/json-c/json-c/issues/243)
-[Error while compiling source from RHEL5, could you please help me to fix this ](https://api.github.com/repos/json-c/json-c/issues/244)
-[json-c compile in window xp](https://api.github.com/repos/json-c/json-c/issues/245)
-[Mac: uselocale failed to build](https://api.github.com/repos/json-c/json-c/issues/246)
-[json_object_array_del_idx function has segment fault error?](https://api.github.com/repos/json-c/json-c/issues/247)
-[Minor changes in C source code](https://api.github.com/repos/json-c/json-c/issues/248)
-[Improving README](https://api.github.com/repos/json-c/json-c/issues/249)
-[Improving .gitignore](https://api.github.com/repos/json-c/json-c/issues/250)
-[Adding a file for EditorConfig](https://api.github.com/repos/json-c/json-c/issues/251)
-[Very minor changes not related to C source code](https://api.github.com/repos/json-c/json-c/issues/252)
-[Adding a test with cppcheck for Travis CI](https://api.github.com/repos/json-c/json-c/issues/253)
-[Very minor changes to some tests](https://api.github.com/repos/json-c/json-c/issues/254)
-[Minor changes in C source code](https://api.github.com/repos/json-c/json-c/issues/255)
-[Mailing list dead?](https://api.github.com/repos/json-c/json-c/issues/256)
-[Defining a coding style](https://api.github.com/repos/json-c/json-c/issues/257)
-[Enable CI services](https://api.github.com/repos/json-c/json-c/issues/258)
-[Fails to parse valid json](https://api.github.com/repos/json-c/json-c/issues/259)
-[Adding an object to itself](https://api.github.com/repos/json-c/json-c/issues/260)
-[Lack of proper documentation](https://api.github.com/repos/json-c/json-c/issues/261)
-[Add Cmakefile and fix compiler warning.](https://api.github.com/repos/json-c/json-c/issues/262)
-[Compiler Warnings with VS2015](https://api.github.com/repos/json-c/json-c/issues/263)
-[successed in simple test while failed in my project](https://api.github.com/repos/json-c/json-c/issues/264)
-[Conformance report for reference](https://api.github.com/repos/json-c/json-c/issues/265)
-[crash perhaps related to reference counting](https://api.github.com/repos/json-c/json-c/issues/266)
-[Removes me as Win32 maintainer, because I'm not.](https://api.github.com/repos/json-c/json-c/issues/267)
-[Documentation of json_object_to_json_string gives no information about memory management](https://api.github.com/repos/json-c/json-c/issues/268)
-[json_object__set(json_object *o, value) API for value setting in json object private structure](https://api.github.com/repos/json-c/json-c/issues/269)
-[new API json_object_new_double_f(doubel d,const char * fmt);](https://api.github.com/repos/json-c/json-c/issues/270)
-[Cannot compile using CMake on macOS](https://api.github.com/repos/json-c/json-c/issues/271)
-[fixed wrong object name in json_object_all_values_equal](https://api.github.com/repos/json-c/json-c/issues/273)
-[Support for 64 bit pointers on Windows](https://api.github.com/repos/json-c/json-c/issues/274)
-[Out-of-bounds read in json_tokener_parse_ex](https://api.github.com/repos/json-c/json-c/issues/275)
-[ ./configure for centos release 6.7(final) failure](https://api.github.com/repos/json-c/json-c/issues/276)
-[Json object set xxx](https://api.github.com/repos/json-c/json-c/issues/277)
-[Serialization of double with no fractional component drops trailing zero](https://api.github.com/repos/json-c/json-c/issues/278)
-[Segmentation fault in array_list_length()](https://api.github.com/repos/json-c/json-c/issues/279)
-[Should json_object_array_get_idx check whether input obj is array? ](https://api.github.com/repos/json-c/json-c/issues/280)
-[how to pretty print json-c? ](https://api.github.com/repos/json-c/json-c/issues/281)
-[ignore temporary files](https://api.github.com/repos/json-c/json-c/issues/282)
-[json_pointer: add first revision based on RFC 6901](https://api.github.com/repos/json-c/json-c/issues/283)
-[Resusing json_tokener object](https://api.github.com/repos/json-c/json-c/issues/284)
-[Revert "compat/strdup.h: move common compat check for strdup() to own](https://api.github.com/repos/json-c/json-c/issues/285)
-[json_tokener_parse_ex() returns json_tokener_continue on zero-length string](https://api.github.com/repos/json-c/json-c/issues/286)
-[json_pointer: extend setter & getter with printf() style arguments](https://api.github.com/repos/json-c/json-c/issues/287)
-[Fix _GNU_SOURCE define for vasprintf](https://api.github.com/repos/json-c/json-c/issues/288)
-[bugfix: floating point representaion without fractional part ](https://api.github.com/repos/json-c/json-c/issues/289)
-[duplicate an json_object](https://api.github.com/repos/json-c/json-c/issues/290)
-[isspace assert error](https://api.github.com/repos/json-c/json-c/issues/291)
-[configure error "./configure: line 13121: syntax error near unexpected token `-Wall'"](https://api.github.com/repos/json-c/json-c/issues/292)
-[how to make with bitcode for ios](https://api.github.com/repos/json-c/json-c/issues/293)
-[Adding UTF-8 validation. Fixes #122](https://api.github.com/repos/json-c/json-c/issues/294)
-[cross compile w/ mingw](https://api.github.com/repos/json-c/json-c/issues/295)
-[Missing functions header in json_object.h](https://api.github.com/repos/json-c/json-c/issues/296)
-[could not parse string to Json object? Like string str=\"helloworld;E\\test\\log\\;end\"](https://api.github.com/repos/json-c/json-c/issues/297)
-[Building using CMake doesn't work](https://api.github.com/repos/json-c/json-c/issues/298)
-[Improve json_object -> string performance](https://api.github.com/repos/json-c/json-c/issues/299)
-[Running tests with MinGW build](https://api.github.com/repos/json-c/json-c/issues/300)
-[How to deep copy json_object in C++ ?](https://api.github.com/repos/json-c/json-c/issues/301)
-[json_tokener_parse_ex doesn't parse JSON values](https://api.github.com/repos/json-c/json-c/issues/302)
-[fix doc in tokener header file](https://api.github.com/repos/json-c/json-c/issues/303)
-[(.text+0x72846): undefined reference to `is_error'](https://api.github.com/repos/json-c/json-c/issues/304)
-[Fix compilation without C-99 option](https://api.github.com/repos/json-c/json-c/issues/305)
-[./configure: line 12748 -error=deprecated-declarations](https://api.github.com/repos/json-c/json-c/issues/306)
-[Memory leak in json_tokener_parse](https://api.github.com/repos/json-c/json-c/issues/307)
-[AM_PROG_LIBTOOL not found on Linux](https://api.github.com/repos/json-c/json-c/issues/308)
-[GCC 7 reports various -Wimplicit-fallthrough= errors](https://api.github.com/repos/json-c/json-c/issues/309)
-[Add FALLTHRU comment to handle GCC7 warnings.](https://api.github.com/repos/json-c/json-c/issues/310)
-[Fix error C3688 when compiling on Visual Studio 2015](https://api.github.com/repos/json-c/json-c/issues/311)
-[Fix CMake Build process improved for MinGW and MSYS2](https://api.github.com/repos/json-c/json-c/issues/312)
-[VERBOSE=1 make check; tests/test_util_file.test.c and tests/test_util_file.expected out of sync](https://api.github.com/repos/json-c/json-c/issues/313)
-[Passing -1 to json_tokener_parse_ex is possibly unsafe](https://api.github.com/repos/json-c/json-c/issues/315)
-[Memory Returned by json_object_to_json_string not freed](https://api.github.com/repos/json-c/json-c/issues/316)
-[json_object_get_string gives segmentation error](https://api.github.com/repos/json-c/json-c/issues/317)
-[PVS-Studio static analyzer analyze results](https://api.github.com/repos/json-c/json-c/issues/318)
-[Windows: Fix dynamic library build with Visual Studio](https://api.github.com/repos/json-c/json-c/issues/319)
-[Can't compile in Mac OS X El Capitan](https://api.github.com/repos/json-c/json-c/issues/320)
-[build,cmake: fix vasprintf implicit definition and generate both static & shared libs](https://api.github.com/repos/json-c/json-c/issues/321)
-[can not link with libjson-c.a](https://api.github.com/repos/json-c/json-c/issues/322)
-[implicit fallthrough detected by gcc 7.1](https://api.github.com/repos/json-c/json-c/issues/323)
-[JsonPath like function?](https://api.github.com/repos/json-c/json-c/issues/324)
-[Fix stack buffer overflow in json_object_double_to_json_string_format()](https://api.github.com/repos/json-c/json-c/issues/325)
-[why json-c so hard to compile](https://api.github.com/repos/json-c/json-c/issues/327)
-[json_object: implement json_object_deep_copy() function](https://api.github.com/repos/json-c/json-c/issues/328)
-[build,cmake: build,cmake: rename libjson-c-static.a to libjson-c.a](https://api.github.com/repos/json-c/json-c/issues/329)
-[tests: symlink basic tests to a single file that has the common code](https://api.github.com/repos/json-c/json-c/issues/330)
-[Safe use of snprintf() / vsnprintf() for Visual studio, and thread-safety fix](https://api.github.com/repos/json-c/json-c/issues/331)
-[Valgrind: invalid read after json_object_array_del_idx.](https://api.github.com/repos/json-c/json-c/issues/332)
-[Replace obsolete AM_PROG_LIBTOOL](https://api.github.com/repos/json-c/json-c/issues/333)
-[README.md: show build status tag from travis-ci.org](https://api.github.com/repos/json-c/json-c/issues/335)
-[tests: fix tests in travis-ci.org](https://api.github.com/repos/json-c/json-c/issues/336)
-[Synchronize "potentially racy" random seed in lh_char_hash()](https://api.github.com/repos/json-c/json-c/issues/337)
-[implement json_object_int_inc(json_object *, int64_t)](https://api.github.com/repos/json-c/json-c/issues/338)
-[Json schema validation](https://api.github.com/repos/json-c/json-c/issues/339)
-[strerror_override: add extern "C" and JSON_EXPORT specifiers for Visual C++ compilers](https://api.github.com/repos/json-c/json-c/issues/340)
-[character "/" parse as "\/"](https://api.github.com/repos/json-c/json-c/issues/341)
-[ No such file or directory "/usr/include/json.h"](https://api.github.com/repos/json-c/json-c/issues/342)
-[Can't parse json](https://api.github.com/repos/json-c/json-c/issues/343)
-[Fix Mingw build](https://api.github.com/repos/json-c/json-c/issues/344)
-[Fix make dist and make distcheck](https://api.github.com/repos/json-c/json-c/issues/345)
-[Clamp double to int32 when narrowing in json_object_get_int.](https://api.github.com/repos/json-c/json-c/issues/346)
-[MSVC linker error json_c_strerror](https://api.github.com/repos/json-c/json-c/issues/347)
-[why](https://api.github.com/repos/json-c/json-c/issues/348)
-[`missing` is missing?](https://api.github.com/repos/json-c/json-c/issues/349)
-[stderror-override and disable-shared](https://api.github.com/repos/json-c/json-c/issues/350)
-[SIZE_T_MAX redefined from limits.h](https://api.github.com/repos/json-c/json-c/issues/351)
-[`INSTALL` overrides an automake script.](https://api.github.com/repos/json-c/json-c/issues/352)
-[Documentation issues](https://api.github.com/repos/json-c/json-c/issues/353)
-[Fixes #351 #352 #353 ](https://api.github.com/repos/json-c/json-c/issues/354)
-[1.make it can been compiled with Visual Studio 2010 by modify the CMakeList.txt and others](https://api.github.com/repos/json-c/json-c/issues/355)
-[VS2008 test test_util_file.cpp err!](https://api.github.com/repos/json-c/json-c/issues/356)
-[__json_c_strerror incompatibility with link-time optimization](https://api.github.com/repos/json-c/json-c/issues/357)
-[make issue](https://api.github.com/repos/json-c/json-c/issues/358)
-[update CMakeLists.txt for compile with visual studio at least 2010](https://api.github.com/repos/json-c/json-c/issues/359)
-[Use strtoll() to parse ints](https://api.github.com/repos/json-c/json-c/issues/360)
-[Fix double to int cast overflow in json_object_get_int64.](https://api.github.com/repos/json-c/json-c/issues/361)
-[CMake Package Config](https://api.github.com/repos/json-c/json-c/issues/362)
-[Issue #338, add json_object_add_int functions](https://api.github.com/repos/json-c/json-c/issues/363)
-[Cmake is Errir](https://api.github.com/repos/json-c/json-c/issues/364)
-[added fallthrough for gcc7](https://api.github.com/repos/json-c/json-c/issues/365)
-[how to check the json string,crash!](https://api.github.com/repos/json-c/json-c/issues/366)
-[Is json-c support "redirect" semantic?](https://api.github.com/repos/json-c/json-c/issues/367)
-[Add examples](https://api.github.com/repos/json-c/json-c/issues/368)
-[How to build json-c library for android?](https://api.github.com/repos/json-c/json-c/issues/369)
-[Compiling using clang-cl](https://api.github.com/repos/json-c/json-c/issues/370)
-[Invalid parsing for Infinity with json-c 0.12](https://api.github.com/repos/json-c/json-c/issues/371)
-[Json-c 0.12: Fixed Infinity bug](https://api.github.com/repos/json-c/json-c/issues/372)
-[build: fix build on appveyor CI](https://api.github.com/repos/json-c/json-c/issues/373)
-[Undefined symbols for architecture x86_64:](https://api.github.com/repos/json-c/json-c/issues/374)
-[what would happened when json_object_object_add add the same key](https://api.github.com/repos/json-c/json-c/issues/375)
-[Eclipse error ](https://api.github.com/repos/json-c/json-c/issues/376)
-[on gcc 7.2.0 on my linux distribution with json-c 2013-04-02 source](https://api.github.com/repos/json-c/json-c/issues/377)
-[ Eclipse: library (libjson-c) not found, but configured](https://api.github.com/repos/json-c/json-c/issues/378)
-[error: this statement may fall through \[-Werror=implicit-fallthrough=\]](https://api.github.com/repos/json-c/json-c/issues/379)
-[Build on Windows](https://api.github.com/repos/json-c/json-c/issues/380)
-[Fix makedist](https://api.github.com/repos/json-c/json-c/issues/381)
-[Memory leak for json_tokener_parse_ex for version 0.12.1](https://api.github.com/repos/json-c/json-c/issues/382)
-[Fix a compiler warning.](https://api.github.com/repos/json-c/json-c/issues/383)
-[Fix a VS 2015 compiler warnings.](https://api.github.com/repos/json-c/json-c/issues/384)
+* [Issue #61](https://github.com/json-c/json-c/issues/61) - Make json_object_object_add() indicate success or failure, test fix \
+* [Issue #113](https://github.com/json-c/json-c/issues/113) - Build fixes (make dist and make distcheck) \
+* [Issue #124](https://github.com/json-c/json-c/issues/124) - Fixing build \
+* [Issue #125](https://github.com/json-c/json-c/issues/125) - Fix compile error(variable size set but not used) on g++4.6 \
+* [Issue #126](https://github.com/json-c/json-c/issues/126) - Removed unused size variable. \
+* [Issue #127](https://github.com/json-c/json-c/issues/127) - remove unused `size` variable \
+* [Issue #128](https://github.com/json-c/json-c/issues/128) - Remove unused variable from json_tokenizer.c \
+* [Issue #130](https://github.com/json-c/json-c/issues/130) - Failed to compile under Ubuntu 13.10 32bit \
+* [Issue #131](https://github.com/json-c/json-c/issues/131) - undefined symbol: __sync_val_compare_and_swap_4 \
+* [Issue #132](https://github.com/json-c/json-c/issues/132) - Remove unused variable 'size' \
+* [Issue #133](https://github.com/json-c/json-c/issues/133) - Update and rename README to README.md \
+* [Issue #134](https://github.com/json-c/json-c/issues/134) - Must remove variable size... \
+* [Issue #135](https://github.com/json-c/json-c/issues/135) - bits.h uses removed json_tokener_errors\[error\] \
+* [Issue #136](https://github.com/json-c/json-c/issues/136) - Error when running make check \
+* [Issue #137](https://github.com/json-c/json-c/issues/137) - config.h.in should not be in git \
+* [Issue #138](https://github.com/json-c/json-c/issues/138) - Can't build on RHEL 6.5 due to dependency on automake-1.14 \
+* [Issue #140](https://github.com/json-c/json-c/issues/140) - Code bug in random_test.c evaluating same expression twice \
+* [Issue #141](https://github.com/json-c/json-c/issues/141) - Removed duplicate check in random_seed test - bug #140 \
+* [Issue #142](https://github.com/json-c/json-c/issues/142) - Please undeprecate json_object_object_get \
+* [Issue #144](https://github.com/json-c/json-c/issues/144) - Introduce json_object_from_fd \
+* [Issue #145](https://github.com/json-c/json-c/issues/145) - Handle % character properly \
+* [Issue #146](https://github.com/json-c/json-c/issues/146) - TAGS rename \
+* [Issue #148](https://github.com/json-c/json-c/issues/148) - Bump the soname \
+* [Issue #149](https://github.com/json-c/json-c/issues/149) - SONAME bump \
+* [Issue #150](https://github.com/json-c/json-c/issues/150) - Fix build using MinGW. \
+* [Issue #151](https://github.com/json-c/json-c/issues/151) - Remove json_type enum trailing comma \
+* [Issue #152](https://github.com/json-c/json-c/issues/152) - error while compiling json-c library version 0.11 \
+* [Issue #153](https://github.com/json-c/json-c/issues/153) - improve doc for json_object_to_json_string() \
+* [Issue #154](https://github.com/json-c/json-c/issues/154) - double precision \
+* [Issue #155](https://github.com/json-c/json-c/issues/155) - add bsearch for arrays \
+* [Issue #156](https://github.com/json-c/json-c/issues/156) - Remove trailing whitespaces \
+* [Issue #157](https://github.com/json-c/json-c/issues/157) - JSON-C shall not exit on calloc fail. \
+* [Issue #158](https://github.com/json-c/json-c/issues/158) - while using json-c 0.11, I am facing strange crash issue in json_object_put. \
+* [Issue #159](https://github.com/json-c/json-c/issues/159) - json_tokener.c compile error \
+* [Issue #160](https://github.com/json-c/json-c/issues/160) - missing header file on windows?? \
+* [Issue #161](https://github.com/json-c/json-c/issues/161) - Is there a way to append to file? \
+* [Issue #162](https://github.com/json-c/json-c/issues/162) - json_util: add directory check for POSIX distros \
+* [Issue #163](https://github.com/json-c/json-c/issues/163) - Fix Win32 build problems \
+* [Issue #164](https://github.com/json-c/json-c/issues/164) - made it compile and link on Widnows (as static library) \
+* [Issue #165](https://github.com/json-c/json-c/issues/165) - json_object_to_json_string_ext length \
+* [Issue #167](https://github.com/json-c/json-c/issues/167) - Can't build on Windows with Visual Studio 2010 \
+* [Issue #168](https://github.com/json-c/json-c/issues/168) - Tightening the number parsing algorithm \
+* [Issue #169](https://github.com/json-c/json-c/issues/169) - Doesn't compile on ubuntu 14.04, 64bit \
+* [Issue #170](https://github.com/json-c/json-c/issues/170) - Generated files in repository \
+* [Issue #171](https://github.com/json-c/json-c/issues/171) - Update configuration for VS2010 and win64 \
+* [Issue #172](https://github.com/json-c/json-c/issues/172) - Adding support for parsing octal numbers \
+* [Issue #173](https://github.com/json-c/json-c/issues/173) - json_parse_int64 doesn't work correctly at illumos \
+* [Issue #174](https://github.com/json-c/json-c/issues/174) - Adding JSON_C_TO_STRING_PRETTY_TAB flag \
+* [Issue #175](https://github.com/json-c/json-c/issues/175) - make check fails 4 tests with overflows when built with ASAN \
+* [Issue #176](https://github.com/json-c/json-c/issues/176) - Possible to delete an array element at a given idx ? \
+* [Issue #177](https://github.com/json-c/json-c/issues/177) - Fix compiler warnings \
+* [Issue #178](https://github.com/json-c/json-c/issues/178) - Unable to compile on CentOS5 \
+* [Issue #179](https://github.com/json-c/json-c/issues/179) - Added array_list_del_idx and json_object_array_del_idx \
+* [Issue #180](https://github.com/json-c/json-c/issues/180) - Enable silent build by default \
+* [Issue #181](https://github.com/json-c/json-c/issues/181) - json_tokener_parse_ex accepts invalid JSON \
+* [Issue #182](https://github.com/json-c/json-c/issues/182) - Link against libm when needed \
+* [Issue #183](https://github.com/json-c/json-c/issues/183) - Apply compile warning fix to master branch \
+* [Issue #184](https://github.com/json-c/json-c/issues/184) - Use only GCC-specific flags when compiling with GCC \
+* [Issue #185](https://github.com/json-c/json-c/issues/185) - compile error \
+* [Issue #186](https://github.com/json-c/json-c/issues/186) - Syntax error \
+* [Issue #187](https://github.com/json-c/json-c/issues/187) - array_list_get_idx and negative indexes. \
+* [Issue #188](https://github.com/json-c/json-c/issues/188) - json_object_object_foreach warnings \
+* [Issue #189](https://github.com/json-c/json-c/issues/189) - noisy json_object_from_file: error opening file \
+* [Issue #190](https://github.com/json-c/json-c/issues/190) - warning: initialization discards const qualifier from pointer target type \[enabled by default\] \
+* [Issue #192](https://github.com/json-c/json-c/issues/192) - json_tokener_parse accepts invalid JSON {"key": "value" , } \
+* [Issue #193](https://github.com/json-c/json-c/issues/193) - Make serialization format of doubles configurable \
+* [Issue #194](https://github.com/json-c/json-c/issues/194) - Add utility function for comparing json_objects \
+* [Issue #195](https://github.com/json-c/json-c/issues/195) - Call uselocale instead of setlocale \
+* [Issue #196](https://github.com/json-c/json-c/issues/196) - Performance improvements \
+* [Issue #197](https://github.com/json-c/json-c/issues/197) - Time for a new release? \
+* [Issue #198](https://github.com/json-c/json-c/issues/198) - Fix possible memory leak and remove superfluous NULL checks before free() \
+* [Issue #199](https://github.com/json-c/json-c/issues/199) - Fix build in Visual Studio \
+* [Issue #200](https://github.com/json-c/json-c/issues/200) - Add build scripts for CI platforms \
+* [Issue #201](https://github.com/json-c/json-c/issues/201) - disable forward-slash escaping? \
+* [Issue #202](https://github.com/json-c/json-c/issues/202) - Array with objects support \
+* [Issue #203](https://github.com/json-c/json-c/issues/203) - Add source position/coordinates to API \
+* [Issue #204](https://github.com/json-c/json-c/issues/204) - json-c/json.h not found \
+* [Issue #205](https://github.com/json-c/json-c/issues/205) - json-c Compiled with Visual Studios \
+* [Issue #206](https://github.com/json-c/json-c/issues/206) - what do i use in place of json_object_object_get? \
+* [Issue #207](https://github.com/json-c/json-c/issues/207) - Add support for property pairs directly added to arrays \
+* [Issue #208](https://github.com/json-c/json-c/issues/208) - Performance enhancements (mainly) to json_object_to_json_string() \
+* [Issue #209](https://github.com/json-c/json-c/issues/209) - fix regression from 2d549662be832da838aa063da2efa78ee3b99668 \
+* [Issue #210](https://github.com/json-c/json-c/issues/210) - Use size_t for arrays \
+* [Issue #211](https://github.com/json-c/json-c/issues/211) - Atomic updates for the refcount \
+* [Issue #212](https://github.com/json-c/json-c/issues/212) - Refcount doesn't work between threads \
+* [Issue #213](https://github.com/json-c/json-c/issues/213) - fix to compile with microsoft visual c++ 2010 \
+* [Issue #214](https://github.com/json-c/json-c/issues/214) - Some non-GNU systems support __sync_val_compare_and_swap \
+* [Issue #215](https://github.com/json-c/json-c/issues/215) - Build json-c for window 64 bit. \
+* [Issue #216](https://github.com/json-c/json-c/issues/216) - configure: check realloc with AC_CHECK_FUNCS() to fix cross-compilation. \
+* [Issue #217](https://github.com/json-c/json-c/issues/217) - Checking for functions in float.h \
+* [Issue #218](https://github.com/json-c/json-c/issues/218) - Use a macro to indicate C99 to the compiler \
+* [Issue #219](https://github.com/json-c/json-c/issues/219) - Fix various potential null ptr deref and int32 overflows \
+* [Issue #220](https://github.com/json-c/json-c/issues/220) - Add utility function for comparing json_objects \
+* [Issue #221](https://github.com/json-c/json-c/issues/221) - JSON_C_TO_STRING_NOSLASHESCAPE works incorrectly \
+* [Issue #222](https://github.com/json-c/json-c/issues/222) - Fix issue #221: JSON_C_TO_STRING_NOSLASHESCAPE works incorrectly \
+* [Issue #223](https://github.com/json-c/json-c/issues/223) - Clarify json_object_get_string documentation of NULL handling & return \
+* [Issue #224](https://github.com/json-c/json-c/issues/224) - json_tokener.c - all warnings being treated as errors \
+* [Issue #225](https://github.com/json-c/json-c/issues/225) - Hi, will you support clib as a "registry"? \
+* [Issue #227](https://github.com/json-c/json-c/issues/227) - Bump SOVERSION to 3 \
+* [Issue #228](https://github.com/json-c/json-c/issues/228) - avoid double slashes from json \
+* [Issue #229](https://github.com/json-c/json-c/issues/229) - configure fails: checking size of size_t... configure: error: cannot determine a size for size_t \
+* [Issue #230](https://github.com/json-c/json-c/issues/230) - Use stdint.h to check for size_t size \
+* [Issue #231](https://github.com/json-c/json-c/issues/231) - Fix size_t size check for first-time builds \
+* [Issue #232](https://github.com/json-c/json-c/issues/232) - tests/tests1: fix printf format for size_t arguments \
+* [Issue #233](https://github.com/json-c/json-c/issues/233) - Include stddef.h in json_object.h \
+* [Issue #234](https://github.com/json-c/json-c/issues/234) - Add public API to use userdata independently of custom serializer \
+* [Issue #235](https://github.com/json-c/json-c/issues/235) - Undefined symbols Error for architecture x86_64 on Mac \
+* [Issue #236](https://github.com/json-c/json-c/issues/236) - Building a project which uses json-c with flag -Wcast-qual causes compilation errors \
+* [Issue #237](https://github.com/json-c/json-c/issues/237) - handle escaped utf-8 \
+* [Issue #238](https://github.com/json-c/json-c/issues/238) - linkhash.c: optimised the table_free path \
+* [Issue #239](https://github.com/json-c/json-c/issues/239) - initialize null terminator of new printbuf \
+* [Issue #240](https://github.com/json-c/json-c/issues/240) - Compile error: Variable set but not used \
+* [Issue #241](https://github.com/json-c/json-c/issues/241) - getting error in date string 19\/07\/2016, fixed for error 19/07/2016 \
+* [Issue #242](https://github.com/json-c/json-c/issues/242) - json_tokener_parse error \
+* [Issue #243](https://github.com/json-c/json-c/issues/243) - Fix #165 \
+* [Issue #244](https://github.com/json-c/json-c/issues/244) - Error while compiling source from RHEL5, could you please help me to fix this \
+* [Issue #245](https://github.com/json-c/json-c/issues/245) - json-c compile in window xp \
+* [Issue #246](https://github.com/json-c/json-c/issues/246) - Mac: uselocale failed to build \
+* [Issue #247](https://github.com/json-c/json-c/issues/247) - json_object_array_del_idx function has segment fault error? \
+* [Issue #248](https://github.com/json-c/json-c/issues/248) - Minor changes in C source code \
+* [Issue #249](https://github.com/json-c/json-c/issues/249) - Improving README \
+* [Issue #250](https://github.com/json-c/json-c/issues/250) - Improving .gitignore \
+* [Issue #251](https://github.com/json-c/json-c/issues/251) - Adding a file for EditorConfig \
+* [Issue #252](https://github.com/json-c/json-c/issues/252) - Very minor changes not related to C source code \
+* [Issue #253](https://github.com/json-c/json-c/issues/253) - Adding a test with cppcheck for Travis CI \
+* [Issue #254](https://github.com/json-c/json-c/issues/254) - Very minor changes to some tests \
+* [Issue #255](https://github.com/json-c/json-c/issues/255) - Minor changes in C source code \
+* [Issue #256](https://github.com/json-c/json-c/issues/256) - Mailing list dead? \
+* [Issue #257](https://github.com/json-c/json-c/issues/257) - Defining a coding style \
+* [Issue #258](https://github.com/json-c/json-c/issues/258) - Enable CI services \
+* [Issue #259](https://github.com/json-c/json-c/issues/259) - Fails to parse valid json \
+* [Issue #260](https://github.com/json-c/json-c/issues/260) - Adding an object to itself \
+* [Issue #261](https://github.com/json-c/json-c/issues/261) - Lack of proper documentation \
+* [Issue #262](https://github.com/json-c/json-c/issues/262) - Add Cmakefile and fix compiler warning. \
+* [Issue #263](https://github.com/json-c/json-c/issues/263) - Compiler Warnings with VS2015 \
+* [Issue #264](https://github.com/json-c/json-c/issues/264) - successed in simple test while failed in my project \
+* [Issue #265](https://github.com/json-c/json-c/issues/265) - Conformance report for reference \
+* [Issue #266](https://github.com/json-c/json-c/issues/266) - crash perhaps related to reference counting \
+* [Issue #267](https://github.com/json-c/json-c/issues/267) - Removes me as Win32 maintainer, because I'm not. \
+* [Issue #268](https://github.com/json-c/json-c/issues/268) - Documentation of json_object_to_json_string gives no information about memory management \
+* [Issue #269](https://github.com/json-c/json-c/issues/269) - json_object__set(json_object *o, value) API for value setting in json object private structure \
+* [Issue #270](https://github.com/json-c/json-c/issues/270) - new API json_object_new_double_f(doubel d,const char * fmt); \
+* [Issue #271](https://github.com/json-c/json-c/issues/271) - Cannot compile using CMake on macOS \
+* [Issue #273](https://github.com/json-c/json-c/issues/273) - fixed wrong object name in json_object_all_values_equal \
+* [Issue #274](https://github.com/json-c/json-c/issues/274) - Support for 64 bit pointers on Windows \
+* [Issue #275](https://github.com/json-c/json-c/issues/275) - Out-of-bounds read in json_tokener_parse_ex \
+* [Issue #276](https://github.com/json-c/json-c/issues/276) - ./configure for centos release 6.7(final) failure \
+* [Issue #277](https://github.com/json-c/json-c/issues/277) - Json object set xxx \
+* [Issue #278](https://github.com/json-c/json-c/issues/278) - Serialization of double with no fractional component drops trailing zero \
+* [Issue #279](https://github.com/json-c/json-c/issues/279) - Segmentation fault in array_list_length() \
+* [Issue #280](https://github.com/json-c/json-c/issues/280) - Should json_object_array_get_idx check whether input obj is array? \
+* [Issue #281](https://github.com/json-c/json-c/issues/281) - how to pretty print json-c? \
+* [Issue #282](https://github.com/json-c/json-c/issues/282) - ignore temporary files \
+* [Issue #283](https://github.com/json-c/json-c/issues/283) - json_pointer: add first revision based on RFC 6901 \
+* [Issue #284](https://github.com/json-c/json-c/issues/284) - Resusing json_tokener object \
+* [Issue #285](https://github.com/json-c/json-c/issues/285) - Revert "compat/strdup.h: move common compat check for strdup() to own \
+* [Issue #286](https://github.com/json-c/json-c/issues/286) - json_tokener_parse_ex() returns json_tokener_continue on zero-length string \
+* [Issue #287](https://github.com/json-c/json-c/issues/287) - json_pointer: extend setter & getter with printf() style arguments \
+* [Issue #288](https://github.com/json-c/json-c/issues/288) - Fix _GNU_SOURCE define for vasprintf \
+* [Issue #289](https://github.com/json-c/json-c/issues/289) - bugfix: floating point representaion without fractional part \
+* [Issue #290](https://github.com/json-c/json-c/issues/290) - duplicate an json_object \
+* [Issue #291](https://github.com/json-c/json-c/issues/291) - isspace assert error \
+* [Issue #292](https://github.com/json-c/json-c/issues/292) - configure error "./configure: line 13121: syntax error near unexpected token `-Wall'" \
+* [Issue #293](https://github.com/json-c/json-c/issues/293) - how to make with bitcode for ios \
+* [Issue #294](https://github.com/json-c/json-c/issues/294) - Adding UTF-8 validation. Fixes #122 \
+* [Issue #295](https://github.com/json-c/json-c/issues/295) - cross compile w/ mingw \
+* [Issue #296](https://github.com/json-c/json-c/issues/296) - Missing functions header in json_object.h \
+* [Issue #297](https://github.com/json-c/json-c/issues/297) - could not parse string to Json object? Like string str=\"helloworld;E\\test\\log\\;end\" \
+* [Issue #298](https://github.com/json-c/json-c/issues/298) - Building using CMake doesn't work \
+* [Issue #299](https://github.com/json-c/json-c/issues/299) - Improve json_object -> string performance \
+* [Issue #300](https://github.com/json-c/json-c/issues/300) - Running tests with MinGW build \
+* [Issue #301](https://github.com/json-c/json-c/issues/301) - How to deep copy json_object in C++ ? \
+* [Issue #302](https://github.com/json-c/json-c/issues/302) - json_tokener_parse_ex doesn't parse JSON values \
+* [Issue #303](https://github.com/json-c/json-c/issues/303) - fix doc in tokener header file \
+* [Issue #304](https://github.com/json-c/json-c/issues/304) - (.text+0x72846): undefined reference to `is_error' \
+* [Issue #305](https://github.com/json-c/json-c/issues/305) - Fix compilation without C-99 option \
+* [Issue #306](https://github.com/json-c/json-c/issues/306) - ./configure: line 12748 -error=deprecated-declarations \
+* [Issue #307](https://github.com/json-c/json-c/issues/307) - Memory leak in json_tokener_parse \
+* [Issue #308](https://github.com/json-c/json-c/issues/308) - AM_PROG_LIBTOOL not found on Linux \
+* [Issue #309](https://github.com/json-c/json-c/issues/309) - GCC 7 reports various -Wimplicit-fallthrough= errors \
+* [Issue #310](https://github.com/json-c/json-c/issues/310) - Add FALLTHRU comment to handle GCC7 warnings. \
+* [Issue #311](https://github.com/json-c/json-c/issues/311) - Fix error C3688 when compiling on Visual Studio 2015 \
+* [Issue #312](https://github.com/json-c/json-c/issues/312) - Fix CMake Build process improved for MinGW and MSYS2 \
+* [Issue #313](https://github.com/json-c/json-c/issues/313) - VERBOSE=1 make check; tests/test_util_file.test.c and tests/test_util_file.expected out of sync \
+* [Issue #315](https://github.com/json-c/json-c/issues/315) - Passing -1 to json_tokener_parse_ex is possibly unsafe \
+* [Issue #316](https://github.com/json-c/json-c/issues/316) - Memory Returned by json_object_to_json_string not freed \
+* [Issue #317](https://github.com/json-c/json-c/issues/317) - json_object_get_string gives segmentation error \
+* [Issue #318](https://github.com/json-c/json-c/issues/318) - PVS-Studio static analyzer analyze results \
+* [Issue #319](https://github.com/json-c/json-c/issues/319) - Windows: Fix dynamic library build with Visual Studio \
+* [Issue #320](https://github.com/json-c/json-c/issues/320) - Can't compile in Mac OS X El Capitan \
+* [Issue #321](https://github.com/json-c/json-c/issues/321) - build,cmake: fix vasprintf implicit definition and generate both static & shared libs \
+* [Issue #322](https://github.com/json-c/json-c/issues/322) - can not link with libjson-c.a \
+* [Issue #323](https://github.com/json-c/json-c/issues/323) - implicit fallthrough detected by gcc 7.1 \
+* [Issue #324](https://github.com/json-c/json-c/issues/324) - JsonPath like function? \
+* [Issue #325](https://github.com/json-c/json-c/issues/325) - Fix stack buffer overflow in json_object_double_to_json_string_format() \
+* [Issue #327](https://github.com/json-c/json-c/issues/327) - why json-c so hard to compile \
+* [Issue #328](https://github.com/json-c/json-c/issues/328) - json_object: implement json_object_deep_copy() function \
+* [Issue #329](https://github.com/json-c/json-c/issues/329) - build,cmake: build,cmake: rename libjson-c-static.a to libjson-c.a \
+* [Issue #330](https://github.com/json-c/json-c/issues/330) - tests: symlink basic tests to a single file that has the common code \
+* [Issue #331](https://github.com/json-c/json-c/issues/331) - Safe use of snprintf() / vsnprintf() for Visual studio, and thread-safety fix \
+* [Issue #332](https://github.com/json-c/json-c/issues/332) - Valgrind: invalid read after json_object_array_del_idx. \
+* [Issue #333](https://github.com/json-c/json-c/issues/333) - Replace obsolete AM_PROG_LIBTOOL \
+* [Issue #335](https://github.com/json-c/json-c/issues/335) - README.md: show build status tag from travis-ci.org \
+* [Issue #336](https://github.com/json-c/json-c/issues/336) - tests: fix tests in travis-ci.org \
+* [Issue #337](https://github.com/json-c/json-c/issues/337) - Synchronize "potentially racy" random seed in lh_char_hash() \
+* [Issue #338](https://github.com/json-c/json-c/issues/338) - implement json_object_int_inc(json_object *, int64_t) \
+* [Issue #339](https://github.com/json-c/json-c/issues/339) - Json schema validation \
+* [Issue #340](https://github.com/json-c/json-c/issues/340) - strerror_override: add extern "C" and JSON_EXPORT specifiers for Visual C++ compilers \
+* [Issue #341](https://github.com/json-c/json-c/issues/341) - character "/" parse as "\/" \
+* [Issue #342](https://github.com/json-c/json-c/issues/342) - No such file or directory "/usr/include/json.h" \
+* [Issue #343](https://github.com/json-c/json-c/issues/343) - Can't parse json \
+* [Issue #344](https://github.com/json-c/json-c/issues/344) - Fix Mingw build \
+* [Issue #345](https://github.com/json-c/json-c/issues/345) - Fix make dist and make distcheck \
+* [Issue #346](https://github.com/json-c/json-c/issues/346) - Clamp double to int32 when narrowing in json_object_get_int. \
+* [Issue #347](https://github.com/json-c/json-c/issues/347) - MSVC linker error json_c_strerror \
+* [Issue #348](https://github.com/json-c/json-c/issues/348) - why \
+* [Issue #349](https://github.com/json-c/json-c/issues/349) - `missing` is missing? \
+* [Issue #350](https://github.com/json-c/json-c/issues/350) - stderror-override and disable-shared \
+* [Issue #351](https://github.com/json-c/json-c/issues/351) - SIZE_T_MAX redefined from limits.h \
+* [Issue #352](https://github.com/json-c/json-c/issues/352) - `INSTALL` overrides an automake script. \
+* [Issue #353](https://github.com/json-c/json-c/issues/353) - Documentation issues \
+* [Issue #354](https://github.com/json-c/json-c/issues/354) - Fixes #351 #352 #353 \
+* [Issue #355](https://github.com/json-c/json-c/issues/355) - 1.make it can been compiled with Visual Studio 2010 by modify the CMakeList.txt and others \
+* [Issue #356](https://github.com/json-c/json-c/issues/356) - VS2008 test test_util_file.cpp err! \
+* [Issue #357](https://github.com/json-c/json-c/issues/357) - __json_c_strerror incompatibility with link-time optimization \
+* [Issue #358](https://github.com/json-c/json-c/issues/358) - make issue \
+* [Issue #359](https://github.com/json-c/json-c/issues/359) - update CMakeLists.txt for compile with visual studio at least 2010 \
+* [Issue #360](https://github.com/json-c/json-c/issues/360) - Use strtoll() to parse ints \
+* [Issue #361](https://github.com/json-c/json-c/issues/361) - Fix double to int cast overflow in json_object_get_int64. \
+* [Issue #362](https://github.com/json-c/json-c/issues/362) - CMake Package Config \
+* [Issue #363](https://github.com/json-c/json-c/issues/363) - Issue #338, add json_object_add_int functions \
+* [Issue #364](https://github.com/json-c/json-c/issues/364) - Cmake is Errir \
+* [Issue #365](https://github.com/json-c/json-c/issues/365) - added fallthrough for gcc7 \
+* [Issue #366](https://github.com/json-c/json-c/issues/366) - how to check the json string,crash! \
+* [Issue #367](https://github.com/json-c/json-c/issues/367) - Is json-c support "redirect" semantic? \
+* [Issue #368](https://github.com/json-c/json-c/issues/368) - Add examples \
+* [Issue #369](https://github.com/json-c/json-c/issues/369) - How to build json-c library for android? \
+* [Issue #370](https://github.com/json-c/json-c/issues/370) - Compiling using clang-cl \
+* [Issue #371](https://github.com/json-c/json-c/issues/371) - Invalid parsing for Infinity with json-c 0.12 \
+* [Issue #372](https://github.com/json-c/json-c/issues/372) - Json-c 0.12: Fixed Infinity bug \
+* [Issue #373](https://github.com/json-c/json-c/issues/373) - build: fix build on appveyor CI \
+* [Issue #374](https://github.com/json-c/json-c/issues/374) - Undefined symbols for architecture x86_64: \
+* [Issue #375](https://github.com/json-c/json-c/issues/375) - what would happened when json_object_object_add add the same key \
+* [Issue #376](https://github.com/json-c/json-c/issues/376) - Eclipse error \
+* [Issue #377](https://github.com/json-c/json-c/issues/377) - on gcc 7.2.0 on my linux distribution with json-c 2013-04-02 source \
+* [Issue #378](https://github.com/json-c/json-c/issues/378) - Eclipse: library (libjson-c) not found, but configured \
+* [Issue #379](https://github.com/json-c/json-c/issues/379) - error: this statement may fall through \[-Werror=implicit-fallthrough=\] \
+* [Issue #380](https://github.com/json-c/json-c/issues/380) - Build on Windows \
+* [Issue #381](https://github.com/json-c/json-c/issues/381) - Fix makedist \
+* [Issue #382](https://github.com/json-c/json-c/issues/382) - Memory leak for json_tokener_parse_ex for version 0.12.1 \
+* [Issue #383](https://github.com/json-c/json-c/issues/383) - Fix a compiler warning. \
+* [Issue #384](https://github.com/json-c/json-c/issues/384) - Fix a VS 2015 compiler warnings. \
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/issues_closed_for_0.14.md thunderbird-91.8.1+build1/comm/third_party/json-c/issues_closed_for_0.14.md
--- thunderbird-91.7.0+build2/comm/third_party/json-c/issues_closed_for_0.14.md 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/issues_closed_for_0.14.md 2022-04-15 07:49:21.000000000 +0000
@@ -0,0 +1,202 @@
+This list was created with:
+
+```
+curl https://api.github.com/search/issues?q="repo%3Ajson-c%2Fjson-c+closed%3A>2017-12-07+created%3A<2020-04-17&sort=created&order=asc&per_page=400&page=1" > issues1.out
+curl https://api.github.com/search/issues?q="repo%3Ajson-c%2Fjson-c+closed%3A>2017-12-07+created%3A<2020-04-17&sort=created&order=asc&per_page=400&page=2" > issues2.out
+curl https://api.github.com/search/issues?q="repo%3Ajson-c%2Fjson-c+closed%3A>2017-12-07+created%3A<2020-04-17&sort=created&order=asc&per_page=400&page=3" > issues3.out
+jq -r '.items[] | "[" + .title + "](" + .url + ")" | tostring' issues?.out > issues.md
+sed -e's,^\[ *\(.*\)\](https://api.github.com/.*/\([0-9].*\)),[Issue #\2](https://github.com/json-c/json-c/issues/\2) - \1,' -i issues.md
+#... manual editing ...
+```
+
+----
+
+Issues and Pull Requests closed for the 0.14 release (since commit d582d3a(2017-12-07) to a911439(2020-04-17))
+
+
+* [Issue #122](https://github.com/json-c/json-c/issues/122) - Add utf-8 validation when parsing strings. \
+* [Issue #139](https://github.com/json-c/json-c/issues/139) - json_object_from_file cannot accept max_depth \
+* [Issue #143](https://github.com/json-c/json-c/issues/143) - RFE / enhancement for full 64-bit signed/unsigned support \
+* [Issue #147](https://github.com/json-c/json-c/issues/147) - Please introduce soname bump if API changed \
+* [Issue #166](https://github.com/json-c/json-c/issues/166) - Need a way to specify nesting depth when opening JSON file \
+* [Issue #226](https://github.com/json-c/json-c/issues/226) - There is no json_object_new_null() \
+* [Issue #314](https://github.com/json-c/json-c/issues/314) - new release ? \
+* [Issue #326](https://github.com/json-c/json-c/issues/326) - Please extend api json_object_get_uint64 \
+* [Issue #334](https://github.com/json-c/json-c/issues/334) - Switch json-c builds to use CMake \
+* [Issue #386](https://github.com/json-c/json-c/issues/386) - Makefile: Add ACLOCAL_AMFLAGS \
+* [Issue #387](https://github.com/json-c/json-c/issues/387) - doc: Use other doxygen feature to specify mainpage \
+* [Issue #388](https://github.com/json-c/json-c/issues/388) - json_object: Add size_t json_object_sizeof() \
+* [Issue #389](https://github.com/json-c/json-c/issues/389) - json_object: Avoid double free (and thus a segfault) when ref_count gets < 0 \
+* [Issue #390](https://github.com/json-c/json-c/issues/390) - json_object: Add const size_t json_c_object_sizeof() \
+* [Issue #391](https://github.com/json-c/json-c/issues/391) - Fix non-GNUC define for JSON_C_CONST_FUNCTION \
+* [Issue #392](https://github.com/json-c/json-c/issues/392) - json_object: Avoid invalid free (and thus a segfault) when ref_count gets < 0 \
+* [Issue #393](https://github.com/json-c/json-c/issues/393) - json_object_private: Use unsigned 32-bit integer type for refcount \
+* [Issue #394](https://github.com/json-c/json-c/issues/394) - Problem serializing double \
+* [Issue #395](https://github.com/json-c/json-c/issues/395) - Key gets modified if it contains "\" \
+* [Issue #396](https://github.com/json-c/json-c/issues/396) - Build failure with no threads uClibc toolchain \
+* [Issue #397](https://github.com/json-c/json-c/issues/397) - update json object with key. \
+* [Issue #398](https://github.com/json-c/json-c/issues/398) - Build failed. \
+* [Issue #399](https://github.com/json-c/json-c/issues/399) - Avoid uninitialized variable warnings \
+* [Issue #400](https://github.com/json-c/json-c/issues/400) - How to generate static lib (.a) \
+* [Issue #401](https://github.com/json-c/json-c/issues/401) - Warnings with Valgrind \
+* [Issue #402](https://github.com/json-c/json-c/issues/402) - Add fuzzers from OSS-Fuzz \
+* [Issue #403](https://github.com/json-c/json-c/issues/403) - Segmentation fault when double quotes is used \
+* [Issue #404](https://github.com/json-c/json-c/issues/404) - valgrind: memory leak \
+* [Issue #405](https://github.com/json-c/json-c/issues/405) - Missing API to determine an object is empty \
+* [Issue #406](https://github.com/json-c/json-c/issues/406) - Undefine NDEBUG for tests \
+* [Issue #407](https://github.com/json-c/json-c/issues/407) - json_tokener_parse is crash \
+* [Issue #408](https://github.com/json-c/json-c/issues/408) - bug in array_list_del_idx when array_list_length()==1 \
+* [Issue #410](https://github.com/json-c/json-c/issues/410) - Fixed typos \
+* [Issue #411](https://github.com/json-c/json-c/issues/411) - Crash- signal SIGSEGV, Segmentation fault. ../sysdeps/x86_64/strlen.S: No such file or directory. \
+* [Issue #412](https://github.com/json-c/json-c/issues/412) - json_type changes during inter process communication. \
+* [Issue #413](https://github.com/json-c/json-c/issues/413) - how to read object of type `json_object *` in c++ \
+* [Issue #414](https://github.com/json-c/json-c/issues/414) - [Question] How JSON-c stores the serialized data in memory? \
+* [Issue #415](https://github.com/json-c/json-c/issues/415) - Resolve windows name conflict \
+* [Issue #416](https://github.com/json-c/json-c/issues/416) - segmentation fault in json_tokener_parse \
+* [Issue #417](https://github.com/json-c/json-c/issues/417) - json_tokener_parse json_object_object_get_ex with string value which is json string \
+* [Issue #418](https://github.com/json-c/json-c/issues/418) - json_object_from_* return value documented incorrectly \
+* [Issue #419](https://github.com/json-c/json-c/issues/419) - Suggestion: document (and define) that json_object_put() accepts NULL pointer to object \
+* [Issue #420](https://github.com/json-c/json-c/issues/420) - arraylist: Fixed names of parameters for callback function \
+* [Issue #421](https://github.com/json-c/json-c/issues/421) - install json_object_iterator.h header file \
+* [Issue #422](https://github.com/json-c/json-c/issues/422) - json_object_get_double() does not set errno when there is no valid conversion \
+* [Issue #423](https://github.com/json-c/json-c/issues/423) - memory leak \
+* [Issue #424](https://github.com/json-c/json-c/issues/424) - Parse string contains "\" or "/" errors \
+* [Issue #425](https://github.com/json-c/json-c/issues/425) - what this is? \
+* [Issue #426](https://github.com/json-c/json-c/issues/426) - __deprecated not supported on clang. \
+* [Issue #427](https://github.com/json-c/json-c/issues/427) - CMake: builds involving this target will not be correct \
+* [Issue #430](https://github.com/json-c/json-c/issues/430) - json_object_object_del() and Segmentation fault \
+* [Issue #431](https://github.com/json-c/json-c/issues/431) - cmake: Bump required version \
+* [Issue #432](https://github.com/json-c/json-c/issues/432) - The real CMake support. \
+* [Issue #433](https://github.com/json-c/json-c/issues/433) - The real CMake support. \
+* [Issue #434](https://github.com/json-c/json-c/issues/434) - The real CMake support \
+* [Issue #435](https://github.com/json-c/json-c/issues/435) - json_object_object_del() segmentation fault \
+* [Issue #436](https://github.com/json-c/json-c/issues/436) - Improve pkgconfig setting \
+* [Issue #437](https://github.com/json-c/json-c/issues/437) - Bad link in README.md \
+* [Issue #438](https://github.com/json-c/json-c/issues/438) - Bad link in README.html \
+* [Issue #439](https://github.com/json-c/json-c/issues/439) - reserved identifier violation \
+* [Issue #440](https://github.com/json-c/json-c/issues/440) - Use of angle brackets around file names for include statements \
+* [Issue #441](https://github.com/json-c/json-c/issues/441) - fix c flag loss during cmake building \
+* [Issue #442](https://github.com/json-c/json-c/issues/442) - error in configure file \
+* [Issue #443](https://github.com/json-c/json-c/issues/443) - remove pretty spaces when using pretty tabs \
+* [Issue #444](https://github.com/json-c/json-c/issues/444) - Document refcount of json_tokener_parse_ex return \
+* [Issue #445](https://github.com/json-c/json-c/issues/445) - Add missing "make check" target to cmake config \
+* [Issue #446](https://github.com/json-c/json-c/issues/446) - Forward slashes get escaped \
+* [Issue #448](https://github.com/json-c/json-c/issues/448) - Buffer overflow in json-c \
+* [Issue #449](https://github.com/json-c/json-c/issues/449) - Need of json_type_int64 returned by json_object_get_type() \
+* [Issue #450](https://github.com/json-c/json-c/issues/450) - Allow use json-c cmake as subproject \
+* [Issue #452](https://github.com/json-c/json-c/issues/452) - Update README.md \
+* [Issue #453](https://github.com/json-c/json-c/issues/453) - Fixed misalignment in JSON string due to space after \n being printed... \
+* [Issue #454](https://github.com/json-c/json-c/issues/454) - json_object_private: save 8 bytes in struct json_object in 64-bit arc… \
+* [Issue #455](https://github.com/json-c/json-c/issues/455) - index.html:fix dead link \
+* [Issue #456](https://github.com/json-c/json-c/issues/456) - STYLE.txt:remove executable permissions \
+* [Issue #457](https://github.com/json-c/json-c/issues/457) - .gitignore:add build directory \
+* [Issue #458](https://github.com/json-c/json-c/issues/458) - README.md:fix dead "file.html" link \
+* [Issue #459](https://github.com/json-c/json-c/issues/459) - README.html:fix link to Doxygen docs, remove WIN32 link \
+* [Issue #460](https://github.com/json-c/json-c/issues/460) - No docs for json_object_new_string_len() \
+* [Issue #461](https://github.com/json-c/json-c/issues/461) - json_object.c:set errno in json_object_get_double() \
+* [Issue #462](https://github.com/json-c/json-c/issues/462) - json_object.h:document json_object_new_string_len() \
+* [Issue #463](https://github.com/json-c/json-c/issues/463) - please check newlocale api first argument valuse. \
+* [Issue #465](https://github.com/json-c/json-c/issues/465) - CMakeLists.txt doesn't contain json_object_iterator.h which json.h includes \
+* [Issue #466](https://github.com/json-c/json-c/issues/466) - configure:3610: error: C compiler cannot create executables \
+* [Issue #467](https://github.com/json-c/json-c/issues/467) - Fix compiler warnings \
+* [Issue #468](https://github.com/json-c/json-c/issues/468) - Fix compiler warnings \
+* [Issue #469](https://github.com/json-c/json-c/issues/469) - Build under alpine with pecl install & docker-php-ext-enable? \
+* [Issue #470](https://github.com/json-c/json-c/issues/470) - cfuhash_foreach_remove doesn't upate cfuhash_num_entries \
+* [Issue #472](https://github.com/json-c/json-c/issues/472) - Segmentation fault in json_object_iter_begin \
+* [Issue #473](https://github.com/json-c/json-c/issues/473) - Convert ChangeLog to valid UTF-8 encoding. \
+* [Issue #474](https://github.com/json-c/json-c/issues/474) - Installation directories empty with CMake in pkg-config. \
+* [Issue #475](https://github.com/json-c/json-c/issues/475) - improvement proposal for json_object_object_foreach \
+* [Issue #477](https://github.com/json-c/json-c/issues/477) - Hang/Crash with large strings \
+* [Issue #478](https://github.com/json-c/json-c/issues/478) - json_object_get_string_len returns 0 when value is number \
+* [Issue #479](https://github.com/json-c/json-c/issues/479) - I want to use it in iOS or Android but I can't compile \
+* [Issue #480](https://github.com/json-c/json-c/issues/480) - json-c-0.12.1 failed making from source code \
+* [Issue #481](https://github.com/json-c/json-c/issues/481) - error while loading shared libraries: libjson-c.so.4 \
+* [Issue #482](https://github.com/json-c/json-c/issues/482) - Error "double free or corruption" after free() \
+* [Issue #483](https://github.com/json-c/json-c/issues/483) - compatible with rarely-used Chinese characters in GBK charset \
+* [Issue #485](https://github.com/json-c/json-c/issues/485) - Install CMake module files \
+* [Issue #486](https://github.com/json-c/json-c/issues/486) - In the case of negative double value, it is formatted without including ".0" \
+* [Issue #488](https://github.com/json-c/json-c/issues/488) - Some APIs are not exported when built as shared lib on Win32 \
+* [Issue #489](https://github.com/json-c/json-c/issues/489) - Don't use -Werror by default \
+* [Issue #490](https://github.com/json-c/json-c/issues/490) - do not compile with -Werror by default \
+* [Issue #491](https://github.com/json-c/json-c/issues/491) - build: add option --disable-werror to configure \
+* [Issue #492](https://github.com/json-c/json-c/issues/492) - lack some quick usage in readme \
+* [Issue #494](https://github.com/json-c/json-c/issues/494) - Code generator? \
+* [Issue #495](https://github.com/json-c/json-c/issues/495) - README.md:fix 2 typos \
+* [Issue #496](https://github.com/json-c/json-c/issues/496) - json_pointer.h:suggest minor grammar improvement for pointer doc \
+* [Issue #497](https://github.com/json-c/json-c/issues/497) - add common header for all tests \
+* [Issue #498](https://github.com/json-c/json-c/issues/498) - double_serializer_test fails (with valgrind) \
+* [Issue #499](https://github.com/json-c/json-c/issues/499) - .travis.yml:test on more recent clang and gcc versions \
+* [Issue #500](https://github.com/json-c/json-c/issues/500) - test/Makefile.am:add missing deps for test1 and test2 \
+* [Issue #501](https://github.com/json-c/json-c/issues/501) - undefine NDEBUG for tests \
+* [Issue #502](https://github.com/json-c/json-c/issues/502) - configure error \
+* [Issue #503](https://github.com/json-c/json-c/issues/503) - json-c retuns OK when Invalid json string is passed \
+* [Issue #504](https://github.com/json-c/json-c/issues/504) - json_object_put coredump \
+* [Issue #505](https://github.com/json-c/json-c/issues/505) - Add vcpkg installation instructions \
+* [Issue #506](https://github.com/json-c/json-c/issues/506) - Cannot parse more than one object \
+* [Issue #509](https://github.com/json-c/json-c/issues/509) - Sometimes a double value is not serialized \
+* [Issue #510](https://github.com/json-c/json-c/issues/510) - Bump so-name and improve CMake \
+* [Issue #511](https://github.com/json-c/json-c/issues/511) - Reduce lines for better optimization \
+* [Issue #512](https://github.com/json-c/json-c/issues/512) - Properly append to CMAKE_C_FLAGS string \
+* [Issue #513](https://github.com/json-c/json-c/issues/513) - What does `userdata` means?And what is the case we can use it? \
+* [Issue #514](https://github.com/json-c/json-c/issues/514) - Json c 0.13 \
+* [Issue #515](https://github.com/json-c/json-c/issues/515) - Mies suomesta fixes segfaults and logic errors \
+* [Issue #516](https://github.com/json-c/json-c/issues/516) - Lja slight mods \
+* [Issue #518](https://github.com/json-c/json-c/issues/518) - Escape character "\\003\", get unexpected value \
+* [Issue #519](https://github.com/json-c/json-c/issues/519) - Add test case obj token \
+* [Issue #520](https://github.com/json-c/json-c/issues/520) - Adding type uint64 \
+* [Issue #521](https://github.com/json-c/json-c/issues/521) - build cmake windows 10 \
+* [Issue #522](https://github.com/json-c/json-c/issues/522) - update json_visit testcase \
+* [Issue #523](https://github.com/json-c/json-c/issues/523) - update tsetcase for tokener_c \
+* [Issue #524](https://github.com/json-c/json-c/issues/524) - Increase coverage \
+* [Issue #525](https://github.com/json-c/json-c/issues/525) - update pointer test case \
+* [Issue #526](https://github.com/json-c/json-c/issues/526) - Increased the test coverage of printbuf.c 82% to 92%. \
+* [Issue #527](https://github.com/json-c/json-c/issues/527) - Arraylist testcase \
+* [Issue #528](https://github.com/json-c/json-c/issues/528) - Solve issue #108. Skip \u0000 while parsing. \
+* [Issue #529](https://github.com/json-c/json-c/issues/529) - Increased the test coverage of json_c_version.c 0% to 100%. \
+* [Issue #530](https://github.com/json-c/json-c/issues/530) - validate utf-8 string before parse \
+* [Issue #531](https://github.com/json-c/json-c/issues/531) - validate utf-8 string \
+* [Issue #532](https://github.com/json-c/json-c/issues/532) - json_object_object_get_ex returning the original object \
+* [Issue #533](https://github.com/json-c/json-c/issues/533) - Fix "make check" \
+* [Issue #535](https://github.com/json-c/json-c/issues/535) - short string optimization: excessive array length \
+* [Issue #536](https://github.com/json-c/json-c/issues/536) - add json_object_new_null() \
+* [Issue #538](https://github.com/json-c/json-c/issues/538) - update shortstring and arraylist parameters \
+* [Issue #539](https://github.com/json-c/json-c/issues/539) - double serializes to the old value after set_double \
+* [Issue #541](https://github.com/json-c/json-c/issues/541) - add coveralls auto tool to json-c \
+* [Issue #542](https://github.com/json-c/json-c/issues/542) - add uint64 data to json-c \
+* [Issue #543](https://github.com/json-c/json-c/issues/543) - Readme \
+* [Issue #544](https://github.com/json-c/json-c/issues/544) - Increase distcheck target in cmake \
+* [Issue #545](https://github.com/json-c/json-c/issues/545) - add doc target in cmake \
+* [Issue #546](https://github.com/json-c/json-c/issues/546) - Add uninstall target in cmake \
+* [Issue #547](https://github.com/json-c/json-c/issues/547) - modify json-c default build type, and fix up the assert() errors in t… \
+* [Issue #548](https://github.com/json-c/json-c/issues/548) - Solve some problems about cmake build type (debug/release) \
+* [Issue #549](https://github.com/json-c/json-c/issues/549) - lib installation issues \
+* [Issue #550](https://github.com/json-c/json-c/issues/550) - Format codes with clang-format tool? \
+* [Issue #551](https://github.com/json-c/json-c/issues/551) - Allow hexadecimal number format convention parsing \
+* [Issue #553](https://github.com/json-c/json-c/issues/553) - Fix/clang ubsan \
+* [Issue #554](https://github.com/json-c/json-c/issues/554) - RFC 8259 compatibility mode \
+* [Issue #555](https://github.com/json-c/json-c/issues/555) - Format json-c with clang-format tool \
+* [Issue #556](https://github.com/json-c/json-c/issues/556) - Fixes various Wreturn-type and Wimplicit-fallthrough errors on Mingw-w64 \
+* [Issue #557](https://github.com/json-c/json-c/issues/557) - Add option in CMAKE to not build documentation \
+* [Issue #558](https://github.com/json-c/json-c/issues/558) - modify the doc target message \
+* [Issue #559](https://github.com/json-c/json-c/issues/559) - json_c_visit() not exported on Windows \
+* [Issue #560](https://github.com/json-c/json-c/issues/560) - error: implicit declaration of function '_strtoi64' \
+* [Issue #561](https://github.com/json-c/json-c/issues/561) - add the badge in README.md and test the coveralls \
+* [Issue #562](https://github.com/json-c/json-c/issues/562) - Bugfix and testcases supplements \
+* [Issue #563](https://github.com/json-c/json-c/issues/563) - Changed order of calloc args to match stdlib \
+* [Issue #564](https://github.com/json-c/json-c/issues/564) - Remove autogenerated files \
+* [Issue #565](https://github.com/json-c/json-c/issues/565) - test the CI and ignore this PR \
+* [Issue #566](https://github.com/json-c/json-c/issues/566) - add the json_types.h to Makefile.am \
+* [Issue #567](https://github.com/json-c/json-c/issues/567) - Install json_types.h with autotools build as well. \
+* [Issue #568](https://github.com/json-c/json-c/issues/568) - Adding better support to MinGW \
+* [Issue #569](https://github.com/json-c/json-c/issues/569) - Handling of -Bsymbolic-function in CMakeLists.txt is deficient \
+* [Issue #571](https://github.com/json-c/json-c/issues/571) - CMake: Bump SONAME to 5. \
+* [Issue #572](https://github.com/json-c/json-c/issues/572) - Small fixes to CMakeLists \
+* [Issue #573](https://github.com/json-c/json-c/issues/573) - Fix coveralls submission. \
+* [Issue #574](https://github.com/json-c/json-c/issues/574) - autogen.sh missing from repository \
+* [Issue #575](https://github.com/json-c/json-c/issues/575) - Small cosmetics. \
+* [Issue #576](https://github.com/json-c/json-c/issues/576) - Test coverage for json_c_version. \
+* [Issue #577](https://github.com/json-c/json-c/issues/577) - Be verbose on failing json_c_version test. \
+* [Issue #578](https://github.com/json-c/json-c/issues/578) - CMake: Install pkgconfig file in proper location by default \
+* [Issue #579](https://github.com/json-c/json-c/issues/579) - Enforce strict prototypes. \
+* [Issue #580](https://github.com/json-c/json-c/issues/580) - Fix CMake tests for enforced strict prototypes. \
+* [Issue #581](https://github.com/json-c/json-c/issues/581) - CMakeLists: do not enforce strict prototypes on Windows. \
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_c_version.c thunderbird-91.8.1+build1/comm/third_party/json-c/json_c_version.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_c_version.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_c_version.c 2022-04-15 07:49:21.000000000 +0000
@@ -17,4 +17,3 @@
{
return JSON_C_VERSION_NUM;
}
-
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_c_version.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_c_version.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_c_version.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_c_version.h 2022-04-15 07:49:22.000000000 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012,2017 Eric Haszlakiewicz
+ * Copyright (c) 2012,2017,2019,2020 Eric Hawicz
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See COPYING for details.
@@ -12,19 +12,30 @@
#ifndef _json_c_version_h_
#define _json_c_version_h_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define JSON_C_MAJOR_VERSION 0
-#define JSON_C_MINOR_VERSION 13
-#define JSON_C_MICRO_VERSION 01
-#define JSON_C_VERSION_NUM ((JSON_C_MAJOR_VERSION << 16) | \
- (JSON_C_MINOR_VERSION << 8) | \
- JSON_C_MICRO_VERSION)
-#define JSON_C_VERSION "0.13.1"
+#define JSON_C_MINOR_VERSION 15
+#define JSON_C_MICRO_VERSION 0
+#define JSON_C_VERSION_NUM \
+ ((JSON_C_MAJOR_VERSION << 16) | (JSON_C_MINOR_VERSION << 8) | JSON_C_MICRO_VERSION)
+#define JSON_C_VERSION "0.15"
+
+#ifndef JSON_EXPORT
+#if defined(_MSC_VER)
+#define JSON_EXPORT __declspec(dllexport)
+#else
+#define JSON_EXPORT extern
+#endif
+#endif
/**
* @see JSON_C_VERSION
* @return the version of the json-c library as a string
*/
-const char *json_c_version(void); /* Returns JSON_C_VERSION */
+JSON_EXPORT const char *json_c_version(void); /* Returns JSON_C_VERSION */
/**
* The json-c version encoded into an int, with the low order 8 bits
@@ -35,6 +46,10 @@
* @see JSON_C_VERSION_NUM
* @return the version of the json-c library as an int
*/
-int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */
+JSON_EXPORT int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */
+
+#ifdef __cplusplus
+}
+#endif
#endif
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json.h thunderbird-91.8.1+build1/comm/third_party/json-c/json.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json.h 2022-04-15 07:49:21.000000000 +0000
@@ -21,15 +21,15 @@
extern "C" {
#endif
-#include "debug.h"
-#include "linkhash.h"
#include "arraylist.h"
-#include "json_util.h"
+#include "debug.h"
+#include "json_c_version.h"
#include "json_object.h"
+#include "json_object_iterator.h"
#include "json_pointer.h"
#include "json_tokener.h"
-#include "json_object_iterator.h"
-#include "json_c_version.h"
+#include "json_util.h"
+#include "linkhash.h"
#ifdef __cplusplus
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_inttypes.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_inttypes.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_inttypes.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_inttypes.h 2022-04-15 07:49:21.000000000 +0000
@@ -17,6 +17,7 @@
#define PRId64 "I64d"
#define SCNd64 "I64d"
+#define PRIu64 "I64u"
#endif
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_object.c thunderbird-91.8.1+build1/comm/third_party/json-c/json_object.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_object.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_object.c 2022-04-15 07:49:22.000000000 +0000
@@ -1,6 +1,4 @@
/*
- * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $
- *
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
* Michael Clark
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
@@ -16,36 +14,123 @@
#include
#include
+#ifdef HAVE_LIMITS_H
+#include
+#endif
+#include
+#include
#include
#include
-#include
#include
-#include
-#include "debug.h"
-#include "printbuf.h"
-#include "linkhash.h"
#include "arraylist.h"
+#include "debug.h"
#include "json_inttypes.h"
#include "json_object.h"
#include "json_object_private.h"
#include "json_util.h"
+#include "linkhash.h"
#include "math_compat.h"
-#include "strdup_compat.h"
+#include "printbuf.h"
#include "snprintf_compat.h"
+#include "strdup_compat.h"
#if SIZEOF_LONG_LONG != SIZEOF_INT64_T
#error "The long long type isn't 64-bits"
#endif
+#ifndef SSIZE_T_MAX
+#if SIZEOF_SSIZE_T == SIZEOF_INT
+#define SSIZE_T_MAX INT_MAX
+#elif SIZEOF_SSIZE_T == SIZEOF_LONG
+#define SSIZE_T_MAX LONG_MAX
+#elif SIZEOF_SSIZE_T == SIZEOF_LONG_LONG
+#define SSIZE_T_MAX LLONG_MAX
+#else
+#error Unable to determine size of ssize_t
+#endif
+#endif
+
// Don't define this. It's not thread-safe.
/* #define REFCOUNT_DEBUG 1 */
-const char *json_number_chars = "0123456789.+-eE";
const char *json_hex_chars = "0123456789abcdefABCDEF";
-static void json_object_generic_delete(struct json_object* jso);
-static struct json_object* json_object_new(enum json_type o_type);
+static void json_object_generic_delete(struct json_object *jso);
+
+#if defined(_MSC_VER) && (_MSC_VER <= 1800)
+/* VS2013 doesn't know about "inline" */
+#define inline __inline
+#elif defined(AIX_CC)
+#define inline
+#endif
+
+/*
+ * Helper functions to more safely cast to a particular type of json_object
+ */
+static inline struct json_object_object *JC_OBJECT(struct json_object *jso)
+{
+ return (void *)jso;
+}
+static inline const struct json_object_object *JC_OBJECT_C(const struct json_object *jso)
+{
+ return (const void *)jso;
+}
+static inline struct json_object_array *JC_ARRAY(struct json_object *jso)
+{
+ return (void *)jso;
+}
+static inline const struct json_object_array *JC_ARRAY_C(const struct json_object *jso)
+{
+ return (const void *)jso;
+}
+static inline struct json_object_boolean *JC_BOOL(struct json_object *jso)
+{
+ return (void *)jso;
+}
+static inline const struct json_object_boolean *JC_BOOL_C(const struct json_object *jso)
+{
+ return (const void *)jso;
+}
+static inline struct json_object_double *JC_DOUBLE(struct json_object *jso)
+{
+ return (void *)jso;
+}
+static inline const struct json_object_double *JC_DOUBLE_C(const struct json_object *jso)
+{
+ return (const void *)jso;
+}
+static inline struct json_object_int *JC_INT(struct json_object *jso)
+{
+ return (void *)jso;
+}
+static inline const struct json_object_int *JC_INT_C(const struct json_object *jso)
+{
+ return (const void *)jso;
+}
+static inline struct json_object_string *JC_STRING(struct json_object *jso)
+{
+ return (void *)jso;
+}
+static inline const struct json_object_string *JC_STRING_C(const struct json_object *jso)
+{
+ return (const void *)jso;
+}
+
+#define JC_CONCAT(a, b) a##b
+#define JC_CONCAT3(a, b, c) a##b##c
+
+#define JSON_OBJECT_NEW(jtype) \
+ (struct JC_CONCAT(json_object_, jtype) *)json_object_new( \
+ JC_CONCAT(json_type_, jtype), sizeof(struct JC_CONCAT(json_object_, jtype)), \
+ &JC_CONCAT3(json_object_, jtype, _to_json_string))
+
+static inline struct json_object *json_object_new(enum json_type o_type, size_t alloc_size,
+ json_object_to_json_string_fn *to_json_string);
+
+static void json_object_object_delete(struct json_object *jso_base);
+static void json_object_string_delete(struct json_object *jso);
+static void json_object_array_delete(struct json_object *jso);
static json_object_to_json_string_fn json_object_object_to_json_string;
static json_object_to_json_string_fn json_object_boolean_to_json_string;
@@ -53,7 +138,26 @@
static json_object_to_json_string_fn json_object_int_to_json_string;
static json_object_to_json_string_fn json_object_string_to_json_string;
static json_object_to_json_string_fn json_object_array_to_json_string;
+static json_object_to_json_string_fn _json_object_userdata_to_json_string;
+#ifndef JSON_NORETURN
+#if defined(_MSC_VER)
+#define JSON_NORETURN __declspec(noreturn)
+#elif defined(__OS400__)
+#define JSON_NORETURN
+#else
+/* 'cold' attribute is for optimization, telling the computer this code
+ * path is unlikely.
+ */
+#define JSON_NORETURN __attribute__((noreturn, cold))
+#endif
+#endif
+/**
+ * Abort and optionally print a message on standard error.
+ * This should be used rather than assert() for unconditional abortion
+ * (in particular for code paths which are never supposed to be run).
+ * */
+JSON_NORETURN static void json_abort(const char *message);
/* ref count debugging */
@@ -61,13 +165,14 @@
static struct lh_table *json_object_table;
-static void json_object_init(void) __attribute__ ((constructor));
-static void json_object_init(void) {
+static void json_object_init(void) __attribute__((constructor));
+static void json_object_init(void)
+{
MC_DEBUG("json_object_init: creating object table\n");
json_object_table = lh_kptr_table_new(128, NULL);
}
-static void json_object_fini(void) __attribute__ ((destructor));
+static void json_object_fini(void) __attribute__((destructor));
static void json_object_fini(void)
{
struct lh_entry *ent;
@@ -76,13 +181,11 @@
if (json_object_table->count)
{
MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
- json_object_table->count);
+ json_object_table->count);
lh_foreach(json_object_table, ent)
{
- struct json_object* obj =
- (struct json_object*) lh_entry_v(ent);
- MC_DEBUG("\t%s:%p\n",
- json_type_to_name(obj->o_type), obj);
+ struct json_object *obj = (struct json_object *)lh_entry_v(ent);
+ MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
}
}
}
@@ -91,26 +194,32 @@
}
#endif /* REFCOUNT_DEBUG */
-
/* helper for accessing the optimized string data component in json_object
*/
-static const char *
-get_string_component(const struct json_object *jso)
+static inline char *get_string_component_mutable(struct json_object *jso)
+{
+ if (JC_STRING_C(jso)->len < 0)
+ {
+ /* Due to json_object_set_string(), we might have a pointer */
+ return JC_STRING(jso)->c_string.pdata;
+ }
+ return JC_STRING(jso)->c_string.idata;
+}
+static inline const char *get_string_component(const struct json_object *jso)
{
- return (jso->o.c_string.len < LEN_DIRECT_STRING_DATA) ?
- jso->o.c_string.str.data : jso->o.c_string.str.ptr;
+ return get_string_component_mutable((void *)(uintptr_t)(const void *)jso);
}
/* string escaping */
-static int json_escape_str(struct printbuf *pb, const char *str, int len, int flags)
+static int json_escape_str(struct printbuf *pb, const char *str, size_t len, int flags)
{
int pos = 0, start_offset = 0;
unsigned char c;
while (len--)
{
c = str[pos];
- switch(c)
+ switch (c)
{
case '\b':
case '\n':
@@ -120,41 +229,47 @@
case '"':
case '\\':
case '/':
- if((flags & JSON_C_TO_STRING_NOSLASHESCAPE) && c == '/')
+ if ((flags & JSON_C_TO_STRING_NOSLASHESCAPE) && c == '/')
{
pos++;
break;
}
- if(pos - start_offset > 0)
+ if (pos - start_offset > 0)
printbuf_memappend(pb, str + start_offset, pos - start_offset);
- if(c == '\b') printbuf_memappend(pb, "\\b", 2);
- else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
- else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
- else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
- else if(c == '\f') printbuf_memappend(pb, "\\f", 2);
- else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
- else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
- else if(c == '/') printbuf_memappend(pb, "\\/", 2);
+ if (c == '\b')
+ printbuf_memappend(pb, "\\b", 2);
+ else if (c == '\n')
+ printbuf_memappend(pb, "\\n", 2);
+ else if (c == '\r')
+ printbuf_memappend(pb, "\\r", 2);
+ else if (c == '\t')
+ printbuf_memappend(pb, "\\t", 2);
+ else if (c == '\f')
+ printbuf_memappend(pb, "\\f", 2);
+ else if (c == '"')
+ printbuf_memappend(pb, "\\\"", 2);
+ else if (c == '\\')
+ printbuf_memappend(pb, "\\\\", 2);
+ else if (c == '/')
+ printbuf_memappend(pb, "\\/", 2);
start_offset = ++pos;
break;
default:
- if(c < ' ')
+ if (c < ' ')
{
char sbuf[7];
- if(pos - start_offset > 0)
- printbuf_memappend(pb,
- str + start_offset,
- pos - start_offset);
- snprintf(sbuf, sizeof(sbuf),
- "\\u00%c%c",
- json_hex_chars[c >> 4],
- json_hex_chars[c & 0xf]);
- printbuf_memappend_fast(pb, sbuf, (int) sizeof(sbuf) - 1);
+ if (pos - start_offset > 0)
+ printbuf_memappend(pb, str + start_offset,
+ pos - start_offset);
+ snprintf(sbuf, sizeof(sbuf), "\\u00%c%c", json_hex_chars[c >> 4],
+ json_hex_chars[c & 0xf]);
+ printbuf_memappend_fast(pb, sbuf, (int)sizeof(sbuf) - 1);
start_offset = ++pos;
- } else
+ }
+ else
pos++;
}
}
@@ -163,25 +278,29 @@
return 0;
}
-
/* reference counting */
-extern struct json_object* json_object_get(struct json_object *jso)
+struct json_object *json_object_get(struct json_object *jso)
{
- if (!jso) return jso;
+ if (!jso)
+ return jso;
+
+ // Don't overflow the refcounter.
+ assert(jso->_ref_count < UINT32_MAX);
#if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING)
__sync_add_and_fetch(&jso->_ref_count, 1);
#else
++jso->_ref_count;
-#endif
+#endif
return jso;
}
int json_object_put(struct json_object *jso)
{
- if(!jso) return 0;
+ if (!jso)
+ return 0;
/* Avoid invalid free and crash explicitly instead of (silently)
* segfaulting.
@@ -190,46 +309,59 @@
#if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING)
/* Note: this only allow the refcount to remain correct
- * when multiple threads are adjusting it. It is still an error
+ * when multiple threads are adjusting it. It is still an error
* for a thread to decrement the refcount if it doesn't "own" it,
* as that can result in the thread that loses the race to 0
* operating on an already-freed object.
*/
- if (__sync_sub_and_fetch(&jso->_ref_count, 1) > 0) return 0;
+ if (__sync_sub_and_fetch(&jso->_ref_count, 1) > 0)
+ return 0;
#else
- if (--jso->_ref_count > 0) return 0;
+ if (--jso->_ref_count > 0)
+ return 0;
#endif
if (jso->_user_delete)
jso->_user_delete(jso, jso->_userdata);
- jso->_delete(jso);
+ switch (jso->o_type)
+ {
+ case json_type_object: json_object_object_delete(jso); break;
+ case json_type_array: json_object_array_delete(jso); break;
+ case json_type_string: json_object_string_delete(jso); break;
+ default: json_object_generic_delete(jso); break;
+ }
return 1;
}
-
/* generic object construction and destruction parts */
-static void json_object_generic_delete(struct json_object* jso)
+static void json_object_generic_delete(struct json_object *jso)
{
#ifdef REFCOUNT_DEBUG
- MC_DEBUG("json_object_delete_%s: %p\n",
- json_type_to_name(jso->o_type), jso);
+ MC_DEBUG("json_object_delete_%s: %p\n", json_type_to_name(jso->o_type), jso);
lh_table_delete(json_object_table, jso);
#endif /* REFCOUNT_DEBUG */
printbuf_free(jso->_pb);
free(jso);
}
-static struct json_object* json_object_new(enum json_type o_type)
+static inline struct json_object *json_object_new(enum json_type o_type, size_t alloc_size,
+ json_object_to_json_string_fn *to_json_string)
{
struct json_object *jso;
- jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
+ jso = (struct json_object *)malloc(alloc_size);
if (!jso)
return NULL;
+
jso->o_type = o_type;
jso->_ref_count = 1;
- jso->_delete = &json_object_generic_delete;
+ jso->_to_json_string = to_json_string;
+ jso->_pb = NULL;
+ jso->_user_delete = NULL;
+ jso->_userdata = NULL;
+ //jso->... // Type-specific fields must be set by caller
+
#ifdef REFCOUNT_DEBUG
lh_table_insert(json_object_table, jso, jso);
MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
@@ -237,7 +369,6 @@
return jso;
}
-
/* type checking functions */
int json_object_is_type(const struct json_object *jso, enum json_type type)
@@ -254,12 +385,12 @@
return jso->o_type;
}
-void* json_object_get_userdata(json_object *jso) {
+void *json_object_get_userdata(json_object *jso)
+{
return jso ? jso->_userdata : NULL;
}
-void json_object_set_userdata(json_object *jso, void *userdata,
- json_object_delete_fn *user_delete)
+void json_object_set_userdata(json_object *jso, void *userdata, json_object_delete_fn *user_delete)
{
// Can't return failure, so abort if we can't perform the operation.
assert(jso != NULL);
@@ -274,30 +405,24 @@
/* set a custom conversion to string */
-void json_object_set_serializer(json_object *jso,
- json_object_to_json_string_fn *to_string_func,
- void *userdata,
- json_object_delete_fn *user_delete)
+void json_object_set_serializer(json_object *jso, json_object_to_json_string_fn *to_string_func,
+ void *userdata, json_object_delete_fn *user_delete)
{
json_object_set_userdata(jso, userdata, user_delete);
if (to_string_func == NULL)
{
// Reset to the standard serialization function
- switch(jso->o_type)
+ switch (jso->o_type)
{
- case json_type_null:
- jso->_to_json_string = NULL;
- break;
+ case json_type_null: jso->_to_json_string = NULL; break;
case json_type_boolean:
jso->_to_json_string = &json_object_boolean_to_json_string;
break;
case json_type_double:
jso->_to_json_string = &json_object_double_to_json_string_default;
break;
- case json_type_int:
- jso->_to_json_string = &json_object_int_to_json_string;
- break;
+ case json_type_int: jso->_to_json_string = &json_object_int_to_json_string; break;
case json_type_object:
jso->_to_json_string = &json_object_object_to_json_string;
break;
@@ -314,10 +439,9 @@
jso->_to_json_string = to_string_func;
}
-
/* extended conversion to string */
-const char* json_object_to_json_string_length(struct json_object *jso, int flags, size_t *length)
+const char *json_object_to_json_string_length(struct json_object *jso, int flags, size_t *length)
{
const char *r = NULL;
size_t s = 0;
@@ -331,7 +455,7 @@
{
printbuf_reset(jso->_pb);
- if(jso->_to_json_string(jso, jso->_pb, 0, flags) >= 0)
+ if (jso->_to_json_string(jso, jso->_pb, 0, flags) >= 0)
{
s = (size_t)jso->_pb->bpos;
r = jso->_pb->buf;
@@ -343,14 +467,14 @@
return r;
}
-const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
+const char *json_object_to_json_string_ext(struct json_object *jso, int flags)
{
return json_object_to_json_string_length(jso, flags, NULL);
}
/* backwards-compatible conversion to string */
-const char* json_object_to_json_string(struct json_object *jso)
+const char *json_object_to_json_string(struct json_object *jso)
{
return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
}
@@ -372,10 +496,8 @@
/* json_object_object */
-static int json_object_object_to_json_string(struct json_object* jso,
- struct printbuf *pb,
- int level,
- int flags)
+static int json_object_object_to_json_string(struct json_object *jso, struct printbuf *pb,
+ int level, int flags)
{
int had_children = 0;
struct json_object_iter iter;
@@ -392,82 +514,74 @@
printbuf_strappend(pb, "\n");
}
had_children = 1;
- if (flags & JSON_C_TO_STRING_SPACED)
+ if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
printbuf_strappend(pb, " ");
- indent(pb, level+1, flags);
+ indent(pb, level + 1, flags);
printbuf_strappend(pb, "\"");
json_escape_str(pb, iter.key, strlen(iter.key), flags);
if (flags & JSON_C_TO_STRING_SPACED)
printbuf_strappend(pb, "\": ");
else
printbuf_strappend(pb, "\":");
- if(iter.val == NULL)
+ if (iter.val == NULL)
printbuf_strappend(pb, "null");
- else
- if (iter.val->_to_json_string(iter.val, pb, level+1,flags) < 0)
- return -1;
+ else if (iter.val->_to_json_string(iter.val, pb, level + 1, flags) < 0)
+ return -1;
}
if (flags & JSON_C_TO_STRING_PRETTY)
{
if (had_children)
printbuf_strappend(pb, "\n");
- indent(pb,level,flags);
+ indent(pb, level, flags);
}
- if (flags & JSON_C_TO_STRING_SPACED)
+ if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
return printbuf_strappend(pb, /*{*/ " }");
else
return printbuf_strappend(pb, /*{*/ "}");
}
-
static void json_object_lh_entry_free(struct lh_entry *ent)
{
if (!ent->k_is_constant)
free(lh_entry_k(ent));
- json_object_put((struct json_object*)lh_entry_v(ent));
+ json_object_put((struct json_object *)lh_entry_v(ent));
}
-static void json_object_object_delete(struct json_object* jso)
+static void json_object_object_delete(struct json_object *jso_base)
{
- lh_table_free(jso->o.c_object);
- json_object_generic_delete(jso);
+ lh_table_free(JC_OBJECT(jso_base)->c_object);
+ json_object_generic_delete(jso_base);
}
-struct json_object* json_object_new_object(void)
+struct json_object *json_object_new_object(void)
{
- struct json_object *jso = json_object_new(json_type_object);
+ struct json_object_object *jso = JSON_OBJECT_NEW(object);
if (!jso)
return NULL;
- jso->_delete = &json_object_object_delete;
- jso->_to_json_string = &json_object_object_to_json_string;
- jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
- &json_object_lh_entry_free);
- if (!jso->o.c_object)
+ jso->c_object =
+ lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES, &json_object_lh_entry_free);
+ if (!jso->c_object)
{
- json_object_generic_delete(jso);
+ json_object_generic_delete(&jso->base);
errno = ENOMEM;
return NULL;
}
- return jso;
+ return &jso->base;
}
-struct lh_table* json_object_get_object(const struct json_object *jso)
+struct lh_table *json_object_get_object(const struct json_object *jso)
{
if (!jso)
return NULL;
- switch(jso->o_type)
+ switch (jso->o_type)
{
- case json_type_object:
- return jso->o.c_object;
- default:
- return NULL;
+ case json_type_object: return JC_OBJECT_C(jso)->c_object;
+ default: return NULL;
}
}
-int json_object_object_add_ex(struct json_object* jso,
- const char *const key,
- struct json_object *const val,
- const unsigned opts)
+int json_object_object_add_ex(struct json_object *jso, const char *const key,
+ struct json_object *const val, const unsigned opts)
{
struct json_object *existing_value = NULL;
struct lh_entry *existing_entry;
@@ -477,10 +591,11 @@
// We lookup the entry and replace the value, rather than just deleting
// and re-adding it, so the existing key remains valid.
- hash = lh_get_hash(jso->o.c_object, (const void *)key);
- existing_entry = (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW) ? NULL :
- lh_table_lookup_entry_w_hash(jso->o.c_object,
- (const void *)key, hash);
+ hash = lh_get_hash(JC_OBJECT(jso)->c_object, (const void *)key);
+ existing_entry =
+ (opts & JSON_C_OBJECT_ADD_KEY_IS_NEW)
+ ? NULL
+ : lh_table_lookup_entry_w_hash(JC_OBJECT(jso)->c_object, (const void *)key, hash);
// The caller must avoid creating loops in the object tree, but do a
// quick check anyway to make sure we're not creating a trivial loop.
@@ -489,30 +604,28 @@
if (!existing_entry)
{
- const void *const k = (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ?
- (const void *)key : strdup(key);
+ const void *const k =
+ (opts & JSON_C_OBJECT_KEY_IS_CONSTANT) ? (const void *)key : strdup(key);
if (k == NULL)
return -1;
- return lh_table_insert_w_hash(jso->o.c_object, k, val, hash, opts);
+ return lh_table_insert_w_hash(JC_OBJECT(jso)->c_object, k, val, hash, opts);
}
- existing_value = (json_object *) lh_entry_v(existing_entry);
+ existing_value = (json_object *)lh_entry_v(existing_entry);
if (existing_value)
json_object_put(existing_value);
existing_entry->v = val;
return 0;
}
-int json_object_object_add(struct json_object* jso, const char *key,
- struct json_object *val)
+int json_object_object_add(struct json_object *jso, const char *key, struct json_object *val)
{
return json_object_object_add_ex(jso, key, val, 0);
}
-
int json_object_object_length(const struct json_object *jso)
{
assert(json_object_get_type(jso) == json_type_object);
- return lh_table_length(jso->o.c_object);
+ return lh_table_length(JC_OBJECT_C(jso)->c_object);
}
size_t json_c_object_sizeof(void)
@@ -520,171 +633,186 @@
return sizeof(struct json_object);
}
-struct json_object* json_object_object_get(const struct json_object* jso,
- const char *key)
+struct json_object *json_object_object_get(const struct json_object *jso, const char *key)
{
struct json_object *result = NULL;
json_object_object_get_ex(jso, key, &result);
return result;
}
-json_bool json_object_object_get_ex(const struct json_object* jso, const char *key,
- struct json_object **value)
+json_bool json_object_object_get_ex(const struct json_object *jso, const char *key,
+ struct json_object **value)
{
if (value != NULL)
*value = NULL;
if (NULL == jso)
- return FALSE;
+ return 0;
- switch(jso->o_type)
+ switch (jso->o_type)
{
case json_type_object:
- return lh_table_lookup_ex(jso->o.c_object, (const void *) key,
- (void**) value);
+ return lh_table_lookup_ex(JC_OBJECT_C(jso)->c_object, (const void *)key,
+ (void **)value);
default:
if (value != NULL)
*value = NULL;
- return FALSE;
+ return 0;
}
}
-void json_object_object_del(struct json_object* jso, const char *key)
+void json_object_object_del(struct json_object *jso, const char *key)
{
assert(json_object_get_type(jso) == json_type_object);
- lh_table_delete(jso->o.c_object, key);
+ lh_table_delete(JC_OBJECT(jso)->c_object, key);
}
-
/* json_object_boolean */
-static int json_object_boolean_to_json_string(struct json_object* jso,
- struct printbuf *pb,
- int level,
- int flags)
+static int json_object_boolean_to_json_string(struct json_object *jso, struct printbuf *pb,
+ int level, int flags)
{
- if (jso->o.c_boolean)
+ if (JC_BOOL(jso)->c_boolean)
return printbuf_strappend(pb, "true");
return printbuf_strappend(pb, "false");
}
-struct json_object* json_object_new_boolean(json_bool b)
+struct json_object *json_object_new_boolean(json_bool b)
{
- struct json_object *jso = json_object_new(json_type_boolean);
+ struct json_object_boolean *jso = JSON_OBJECT_NEW(boolean);
if (!jso)
return NULL;
- jso->_to_json_string = &json_object_boolean_to_json_string;
- jso->o.c_boolean = b;
- return jso;
+ jso->c_boolean = b;
+ return &jso->base;
}
json_bool json_object_get_boolean(const struct json_object *jso)
{
if (!jso)
- return FALSE;
- switch(jso->o_type)
+ return 0;
+ switch (jso->o_type)
{
- case json_type_boolean:
- return jso->o.c_boolean;
+ case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
case json_type_int:
- return (jso->o.c_int64 != 0);
- case json_type_double:
- return (jso->o.c_double != 0);
- case json_type_string:
- return (jso->o.c_string.len != 0);
- default:
- return FALSE;
+ switch (JC_INT_C(jso)->cint_type)
+ {
+ case json_object_int_type_int64: return (JC_INT_C(jso)->cint.c_int64 != 0);
+ case json_object_int_type_uint64: return (JC_INT_C(jso)->cint.c_uint64 != 0);
+ default: json_abort("invalid cint_type");
+ }
+ case json_type_double: return (JC_DOUBLE_C(jso)->c_double != 0);
+ case json_type_string: return (JC_STRING_C(jso)->len != 0);
+ default: return 0;
}
}
-int json_object_set_boolean(struct json_object *jso,json_bool new_value){
- if (!jso || jso->o_type!=json_type_boolean)
+int json_object_set_boolean(struct json_object *jso, json_bool new_value)
+{
+ if (!jso || jso->o_type != json_type_boolean)
return 0;
- jso->o.c_boolean=new_value;
+ JC_BOOL(jso)->c_boolean = new_value;
return 1;
}
-
/* json_object_int */
-static int json_object_int_to_json_string(struct json_object* jso,
- struct printbuf *pb,
- int level,
- int flags)
+static int json_object_int_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
+ int flags)
{
/* room for 19 digits, the sign char, and a null term */
char sbuf[21];
- snprintf(sbuf, sizeof(sbuf), "%" PRId64, jso->o.c_int64);
- return printbuf_memappend (pb, sbuf, strlen(sbuf));
+ if (JC_INT(jso)->cint_type == json_object_int_type_int64)
+ snprintf(sbuf, sizeof(sbuf), "%" PRId64, JC_INT(jso)->cint.c_int64);
+ else
+ snprintf(sbuf, sizeof(sbuf), "%" PRIu64, JC_INT(jso)->cint.c_uint64);
+ return printbuf_memappend(pb, sbuf, strlen(sbuf));
}
-struct json_object* json_object_new_int(int32_t i)
+struct json_object *json_object_new_int(int32_t i)
{
- struct json_object *jso = json_object_new(json_type_int);
- if (!jso)
- return NULL;
- jso->_to_json_string = &json_object_int_to_json_string;
- jso->o.c_int64 = i;
- return jso;
+ return json_object_new_int64(i);
}
int32_t json_object_get_int(const struct json_object *jso)
{
- int64_t cint64;
- enum json_type o_type;
+ int64_t cint64=0;
+ double cdouble;
+ enum json_type o_type;
- if(!jso) return 0;
+ if (!jso)
+ return 0;
+
+ o_type = jso->o_type;
+ if (o_type == json_type_int)
+ {
+ const struct json_object_int *jsoint = JC_INT_C(jso);
+ if (jsoint->cint_type == json_object_int_type_int64)
+ {
+ cint64 = jsoint->cint.c_int64;
+ }
+ else
+ {
+ if (jsoint->cint.c_uint64 >= INT64_MAX)
+ cint64 = INT64_MAX;
+ else
+ cint64 = (int64_t)jsoint->cint.c_uint64;
+ }
+ }
+ else if (o_type == json_type_string)
+ {
+ /*
+ * Parse strings into 64-bit numbers, then use the
+ * 64-to-32-bit number handling below.
+ */
+ if (json_parse_int64(get_string_component(jso), &cint64) != 0)
+ return 0; /* whoops, it didn't work. */
+ o_type = json_type_int;
+ }
- o_type = jso->o_type;
- cint64 = jso->o.c_int64;
+ switch (o_type)
+ {
+ case json_type_int:
+ /* Make sure we return the correct values for out of range numbers. */
+ if (cint64 <= INT32_MIN)
+ return INT32_MIN;
+ if (cint64 >= INT32_MAX)
+ return INT32_MAX;
+ return (int32_t)cint64;
+ case json_type_double:
+ cdouble = JC_DOUBLE_C(jso)->c_double;
+ if (cdouble <= INT32_MIN)
+ return INT32_MIN;
+ if (cdouble >= INT32_MAX)
+ return INT32_MAX;
+ return (int32_t)cdouble;
+ case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
+ default: return 0;
+ }
+}
- if (o_type == json_type_string)
- {
- /*
- * Parse strings into 64-bit numbers, then use the
- * 64-to-32-bit number handling below.
- */
- if (json_parse_int64(get_string_component(jso), &cint64) != 0)
- return 0; /* whoops, it didn't work. */
- o_type = json_type_int;
- }
-
- switch(o_type) {
- case json_type_int:
- /* Make sure we return the correct values for out of range numbers. */
- if (cint64 <= INT32_MIN)
- return INT32_MIN;
- if (cint64 >= INT32_MAX)
- return INT32_MAX;
- return (int32_t) cint64;
- case json_type_double:
- if (jso->o.c_double <= INT32_MIN)
- return INT32_MIN;
- if (jso->o.c_double >= INT32_MAX)
- return INT32_MAX;
- return (int32_t)jso->o.c_double;
- case json_type_boolean:
- return jso->o.c_boolean;
- default:
- return 0;
- }
+int json_object_set_int(struct json_object *jso, int new_value)
+{
+ return json_object_set_int64(jso, (int64_t)new_value);
}
-int json_object_set_int(struct json_object *jso,int new_value){
- if (!jso || jso->o_type!=json_type_int)
- return 0;
- jso->o.c_int64=new_value;
- return 1;
+struct json_object *json_object_new_int64(int64_t i)
+{
+ struct json_object_int *jso = JSON_OBJECT_NEW(int);
+ if (!jso)
+ return NULL;
+ jso->cint.c_int64 = i;
+ jso->cint_type = json_object_int_type_int64;
+ return &jso->base;
}
-struct json_object* json_object_new_int64(int64_t i)
+struct json_object *json_object_new_uint64(uint64_t i)
{
- struct json_object *jso = json_object_new(json_type_int);
+ struct json_object_int *jso = JSON_OBJECT_NEW(int);
if (!jso)
return NULL;
- jso->_to_json_string = &json_object_int_to_json_string;
- jso->o.c_int64 = i;
- return jso;
+ jso->cint.c_uint64 = i;
+ jso->cint_type = json_object_int_type_uint64;
+ return &jso->base;
}
int64_t json_object_get_int64(const struct json_object *jso)
@@ -693,47 +821,140 @@
if (!jso)
return 0;
- switch(jso->o_type)
+ switch (jso->o_type)
{
case json_type_int:
- return jso->o.c_int64;
+ {
+ const struct json_object_int *jsoint = JC_INT_C(jso);
+ switch (jsoint->cint_type)
+ {
+ case json_object_int_type_int64: return jsoint->cint.c_int64;
+ case json_object_int_type_uint64:
+ if (jsoint->cint.c_uint64 >= INT64_MAX)
+ return INT64_MAX;
+ return (int64_t)jsoint->cint.c_uint64;
+ default: json_abort("invalid cint_type");
+ }
+ }
case json_type_double:
- if (jso->o.c_double >= INT64_MAX)
+ // INT64_MAX can't be exactly represented as a double
+ // so cast to tell the compiler it's ok to round up.
+ if (JC_DOUBLE_C(jso)->c_double >= (double)INT64_MAX)
return INT64_MAX;
- if (jso->o.c_double <= INT64_MIN)
+ if (JC_DOUBLE_C(jso)->c_double <= INT64_MIN)
return INT64_MIN;
- return (int64_t)jso->o.c_double;
- case json_type_boolean:
- return jso->o.c_boolean;
+ return (int64_t)JC_DOUBLE_C(jso)->c_double;
+ case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
case json_type_string:
if (json_parse_int64(get_string_component(jso), &cint) == 0)
return cint;
/* FALLTHRU */
- default:
+ default: return 0;
+ }
+}
+
+uint64_t json_object_get_uint64(const struct json_object *jso)
+{
+ uint64_t cuint;
+
+ if (!jso)
return 0;
+ switch (jso->o_type)
+ {
+ case json_type_int:
+ {
+ const struct json_object_int *jsoint = JC_INT_C(jso);
+ switch (jsoint->cint_type)
+ {
+ case json_object_int_type_int64:
+ if (jsoint->cint.c_int64 < 0)
+ return 0;
+ return (uint64_t)jsoint->cint.c_int64;
+ case json_object_int_type_uint64: return jsoint->cint.c_uint64;
+ default: json_abort("invalid cint_type");
+ }
+ }
+ case json_type_double:
+ // UINT64_MAX can't be exactly represented as a double
+ // so cast to tell the compiler it's ok to round up.
+ if (JC_DOUBLE_C(jso)->c_double >= (double)UINT64_MAX)
+ return UINT64_MAX;
+ if (JC_DOUBLE_C(jso)->c_double < 0)
+ return 0;
+ return (uint64_t)JC_DOUBLE_C(jso)->c_double;
+ case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
+ case json_type_string:
+ if (json_parse_uint64(get_string_component(jso), &cuint) == 0)
+ return cuint;
+ /* FALLTHRU */
+ default: return 0;
}
}
-int json_object_set_int64(struct json_object *jso,int64_t new_value){
- if (!jso || jso->o_type!=json_type_int)
+int json_object_set_int64(struct json_object *jso, int64_t new_value)
+{
+ if (!jso || jso->o_type != json_type_int)
return 0;
- jso->o.c_int64=new_value;
+ JC_INT(jso)->cint.c_int64 = new_value;
+ JC_INT(jso)->cint_type = json_object_int_type_int64;
return 1;
}
-int json_object_int_inc(struct json_object *jso, int64_t val) {
+int json_object_set_uint64(struct json_object *jso, uint64_t new_value)
+{
if (!jso || jso->o_type != json_type_int)
return 0;
- if (val > 0 && jso->o.c_int64 > INT64_MAX - val) {
- jso->o.c_int64 = INT64_MAX;
- } else if (val < 0 && jso->o.c_int64 < INT64_MIN - val) {
- jso->o.c_int64 = INT64_MIN;
- } else {
- jso->o.c_int64 += val;
- }
+ JC_INT(jso)->cint.c_uint64 = new_value;
+ JC_INT(jso)->cint_type = json_object_int_type_uint64;
return 1;
}
+int json_object_int_inc(struct json_object *jso, int64_t val)
+{
+ struct json_object_int *jsoint;
+ if (!jso || jso->o_type != json_type_int)
+ return 0;
+ jsoint = JC_INT(jso);
+ switch (jsoint->cint_type)
+ {
+ case json_object_int_type_int64:
+ if (val > 0 && jsoint->cint.c_int64 > INT64_MAX - val)
+ {
+ jsoint->cint.c_uint64 = (uint64_t)jsoint->cint.c_int64 + (uint64_t)val;
+ jsoint->cint_type = json_object_int_type_uint64;
+ }
+ else if (val < 0 && jsoint->cint.c_int64 < INT64_MIN - val)
+ {
+ jsoint->cint.c_int64 = INT64_MIN;
+ }
+ else
+ {
+ jsoint->cint.c_int64 += val;
+ }
+ return 1;
+ case json_object_int_type_uint64:
+ if (val > 0 && jsoint->cint.c_uint64 > UINT64_MAX - (uint64_t)val)
+ {
+ jsoint->cint.c_uint64 = UINT64_MAX;
+ }
+ else if (val < 0 && jsoint->cint.c_uint64 < (uint64_t)(-val))
+ {
+ jsoint->cint.c_int64 = (int64_t)jsoint->cint.c_uint64 + val;
+ jsoint->cint_type = json_object_int_type_int64;
+ }
+ else if (val < 0 && jsoint->cint.c_uint64 >= (uint64_t)(-val))
+ {
+ jsoint->cint.c_uint64 -= (uint64_t)(-val);
+ }
+ else
+ {
+ jsoint->cint.c_uint64 += val;
+ }
+ return 1;
+ default: json_abort("invalid cint_type");
+ }
+}
+
/* json_object_double */
#if defined(HAVE___THREAD)
@@ -773,32 +994,31 @@
}
else
{
- _json_c_set_last_err("json_c_set_option: invalid global_or_thread value: %d\n", global_or_thread);
+ _json_c_set_last_err("json_c_set_option: invalid global_or_thread value: %d\n",
+ global_or_thread);
return -1;
}
return 0;
}
-
-static int json_object_double_to_json_string_format(struct json_object* jso,
- struct printbuf *pb,
- int level,
- int flags,
- const char *format)
+static int json_object_double_to_json_string_format(struct json_object *jso, struct printbuf *pb,
+ int level, int flags, const char *format)
{
+ struct json_object_double *jsodbl = JC_DOUBLE(jso);
char buf[128], *p, *q;
int size;
/* Although JSON RFC does not support
- NaN or Infinity as numeric values
- ECMA 262 section 9.8.1 defines
- how to handle these cases as strings */
- if (isnan(jso->o.c_double))
+ * NaN or Infinity as numeric values
+ * ECMA 262 section 9.8.1 defines
+ * how to handle these cases as strings
+ */
+ if (isnan(jsodbl->c_double))
{
size = snprintf(buf, sizeof(buf), "NaN");
}
- else if (isinf(jso->o.c_double))
+ else if (isinf(jsodbl->c_double))
{
- if(jso->o.c_double > 0)
+ if (jsodbl->c_double > 0)
size = snprintf(buf, sizeof(buf), "Infinity");
else
size = snprintf(buf, sizeof(buf), "-Infinity");
@@ -807,6 +1027,7 @@
{
const char *std_format = "%.17g";
int format_drops_decimals = 0;
+ int looks_numeric = 0;
if (!format)
{
@@ -815,12 +1036,12 @@
format = tls_serialization_float_format;
else
#endif
- if (global_serialization_float_format)
+ if (global_serialization_float_format)
format = global_serialization_float_format;
else
format = std_format;
}
- size = snprintf(buf, sizeof(buf), format, jso->o.c_double);
+ size = snprintf(buf, sizeof(buf), format, jsodbl->c_double);
if (size < 0)
return -1;
@@ -834,11 +1055,13 @@
if (format == std_format || strstr(format, ".0f") == NULL)
format_drops_decimals = 1;
- if (size < (int)sizeof(buf) - 2 &&
- isdigit((int)buf[0]) && /* Looks like *some* kind of number */
- !p && /* Has no decimal point */
+ looks_numeric = /* Looks like *some* kind of number */
+ isdigit((unsigned char)buf[0]) ||
+ (size > 1 && buf[0] == '-' && isdigit((unsigned char)buf[1]));
+
+ if (size < (int)sizeof(buf) - 2 && looks_numeric && !p && /* Has no decimal point */
strchr(buf, 'e') == NULL && /* Not scientific notation */
- format_drops_decimals)
+ format_drops_decimals)
{
// Ensure it looks like a float, even if snprintf didn't,
// unless a custom format is set to omit the decimal.
@@ -849,12 +1072,15 @@
{
/* last useful digit, always keep 1 zero */
p++;
- for (q=p ; *q ; q++) {
- if (*q!='0') p=q;
+ for (q = p; *q; q++)
+ {
+ if (*q != '0')
+ p = q;
}
/* drop trailing zeroes */
- *(++p) = 0;
- size = p-buf;
+ if (*p != 0)
+ *(++p) = 0;
+ size = p - buf;
}
}
// although unlikely, snprintf can fail
@@ -869,35 +1095,30 @@
return size;
}
-static int json_object_double_to_json_string_default(struct json_object* jso,
- struct printbuf *pb,
- int level,
- int flags)
+static int json_object_double_to_json_string_default(struct json_object *jso, struct printbuf *pb,
+ int level, int flags)
{
- return json_object_double_to_json_string_format(jso, pb, level, flags,
- NULL);
+ return json_object_double_to_json_string_format(jso, pb, level, flags, NULL);
}
-int json_object_double_to_json_string(struct json_object* jso,
- struct printbuf *pb,
- int level,
- int flags)
+int json_object_double_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
+ int flags)
{
return json_object_double_to_json_string_format(jso, pb, level, flags,
- (const char *)jso->_userdata);
+ (const char *)jso->_userdata);
}
-struct json_object* json_object_new_double(double d)
+struct json_object *json_object_new_double(double d)
{
- struct json_object *jso = json_object_new(json_type_double);
+ struct json_object_double *jso = JSON_OBJECT_NEW(double);
if (!jso)
return NULL;
- jso->_to_json_string = &json_object_double_to_json_string_default;
- jso->o.c_double = d;
- return jso;
+ jso->base._to_json_string = &json_object_double_to_json_string_default;
+ jso->c_double = d;
+ return &jso->base;
}
-struct json_object* json_object_new_double_s(double d, const char *ds)
+struct json_object *json_object_new_double_s(double d, const char *ds)
{
char *new_ds;
struct json_object *jso = json_object_new_double(d);
@@ -911,13 +1132,24 @@
errno = ENOMEM;
return NULL;
}
- json_object_set_serializer(jso, json_object_userdata_to_json_string,
- new_ds, json_object_free_userdata);
+ json_object_set_serializer(jso, _json_object_userdata_to_json_string, new_ds,
+ json_object_free_userdata);
return jso;
}
-int json_object_userdata_to_json_string(struct json_object *jso,
- struct printbuf *pb, int level, int flags)
+/*
+ * A wrapper around json_object_userdata_to_json_string() used only
+ * by json_object_new_double_s() just so json_object_set_double() can
+ * detect when it needs to reset the serializer to the default.
+ */
+static int _json_object_userdata_to_json_string(struct json_object *jso, struct printbuf *pb,
+ int level, int flags)
+{
+ return json_object_userdata_to_json_string(jso, pb, level, flags);
+}
+
+int json_object_userdata_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
+ int flags)
{
int userdata_len = strlen((const char *)jso->_userdata);
printbuf_memappend(pb, (const char *)jso->_userdata, userdata_len);
@@ -931,181 +1163,222 @@
double json_object_get_double(const struct json_object *jso)
{
- double cdouble;
- char *errPtr = NULL;
+ double cdouble;
+ char *errPtr = NULL;
+
+ if (!jso)
+ return 0.0;
+ switch (jso->o_type)
+ {
+ case json_type_double: return JC_DOUBLE_C(jso)->c_double;
+ case json_type_int:
+ switch (JC_INT_C(jso)->cint_type)
+ {
+ case json_object_int_type_int64: return JC_INT_C(jso)->cint.c_int64;
+ case json_object_int_type_uint64: return JC_INT_C(jso)->cint.c_uint64;
+ default: json_abort("invalid cint_type");
+ }
+ case json_type_boolean: return JC_BOOL_C(jso)->c_boolean;
+ case json_type_string:
+ errno = 0;
+ cdouble = strtod(get_string_component(jso), &errPtr);
+
+ /* if conversion stopped at the first character, return 0.0 */
+ if (errPtr == get_string_component(jso))
+ {
+ errno = EINVAL;
+ return 0.0;
+ }
+
+ /*
+ * Check that the conversion terminated on something sensible
+ *
+ * For example, { "pay" : 123AB } would parse as 123.
+ */
+ if (*errPtr != '\0')
+ {
+ errno = EINVAL;
+ return 0.0;
+ }
- if(!jso) return 0.0;
- switch(jso->o_type) {
- case json_type_double:
- return jso->o.c_double;
- case json_type_int:
- return jso->o.c_int64;
- case json_type_boolean:
- return jso->o.c_boolean;
- case json_type_string:
- errno = 0;
- cdouble = strtod(get_string_component(jso), &errPtr);
-
- /* if conversion stopped at the first character, return 0.0 */
- if (errPtr == get_string_component(jso))
- return 0.0;
-
- /*
- * Check that the conversion terminated on something sensible
- *
- * For example, { "pay" : 123AB } would parse as 123.
- */
- if (*errPtr != '\0')
- return 0.0;
-
- /*
- * If strtod encounters a string which would exceed the
- * capacity of a double, it returns +/- HUGE_VAL and sets
- * errno to ERANGE. But +/- HUGE_VAL is also a valid result
- * from a conversion, so we need to check errno.
- *
- * Underflow also sets errno to ERANGE, but it returns 0 in
- * that case, which is what we will return anyway.
- *
- * See CERT guideline ERR30-C
- */
- if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) &&
- (ERANGE == errno))
- cdouble = 0.0;
- return cdouble;
- default:
- return 0.0;
- }
+ /*
+ * If strtod encounters a string which would exceed the
+ * capacity of a double, it returns +/- HUGE_VAL and sets
+ * errno to ERANGE. But +/- HUGE_VAL is also a valid result
+ * from a conversion, so we need to check errno.
+ *
+ * Underflow also sets errno to ERANGE, but it returns 0 in
+ * that case, which is what we will return anyway.
+ *
+ * See CERT guideline ERR30-C
+ */
+ if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) && (ERANGE == errno))
+ cdouble = 0.0;
+ return cdouble;
+ default: errno = EINVAL; return 0.0;
+ }
}
-int json_object_set_double(struct json_object *jso,double new_value){
- if (!jso || jso->o_type!=json_type_double)
+int json_object_set_double(struct json_object *jso, double new_value)
+{
+ if (!jso || jso->o_type != json_type_double)
return 0;
- jso->o.c_double=new_value;
+ JC_DOUBLE(jso)->c_double = new_value;
+ if (jso->_to_json_string == &_json_object_userdata_to_json_string)
+ json_object_set_serializer(jso, NULL, NULL, NULL);
return 1;
}
/* json_object_string */
-static int json_object_string_to_json_string(struct json_object* jso,
- struct printbuf *pb,
- int level,
- int flags)
+static int json_object_string_to_json_string(struct json_object *jso, struct printbuf *pb,
+ int level, int flags)
{
+ ssize_t len = JC_STRING(jso)->len;
printbuf_strappend(pb, "\"");
- json_escape_str(pb, get_string_component(jso), jso->o.c_string.len, flags);
+ json_escape_str(pb, get_string_component(jso), len < 0 ? -(ssize_t)len : len, flags);
printbuf_strappend(pb, "\"");
return 0;
}
-static void json_object_string_delete(struct json_object* jso)
+static void json_object_string_delete(struct json_object *jso)
{
- if(jso->o.c_string.len >= LEN_DIRECT_STRING_DATA)
- free(jso->o.c_string.str.ptr);
+ if (JC_STRING(jso)->len < 0)
+ free(JC_STRING(jso)->c_string.pdata);
json_object_generic_delete(jso);
}
-struct json_object* json_object_new_string(const char *s)
+static struct json_object *_json_object_new_string(const char *s, const size_t len)
{
- struct json_object *jso = json_object_new(json_type_string);
+ size_t objsize;
+ struct json_object_string *jso;
+
+ /*
+ * Structures Actual memory layout
+ * ------------------- --------------------
+ * [json_object_string [json_object_string
+ * [json_object] [json_object]
+ * ...other fields... ...other fields...
+ * c_string] len
+ * bytes
+ * of
+ * string
+ * data
+ * \0]
+ */
+ if (len > (SSIZE_T_MAX - (sizeof(*jso) - sizeof(jso->c_string)) - 1))
+ return NULL;
+ objsize = (sizeof(*jso) - sizeof(jso->c_string)) + len + 1;
+ if (len < sizeof(void *))
+ // We need a minimum size to support json_object_set_string() mutability
+ // so we can stuff a pointer into pdata :(
+ objsize += sizeof(void *) - len;
+
+ jso = (struct json_object_string *)json_object_new(json_type_string, objsize,
+ &json_object_string_to_json_string);
+
if (!jso)
return NULL;
- jso->_delete = &json_object_string_delete;
- jso->_to_json_string = &json_object_string_to_json_string;
- jso->o.c_string.len = strlen(s);
- if(jso->o.c_string.len < LEN_DIRECT_STRING_DATA) {
- memcpy(jso->o.c_string.str.data, s, jso->o.c_string.len);
- } else {
- jso->o.c_string.str.ptr = strdup(s);
- if (!jso->o.c_string.str.ptr)
- {
- json_object_generic_delete(jso);
- errno = ENOMEM;
- return NULL;
- }
- }
- return jso;
+ jso->len = len;
+ memcpy(jso->c_string.idata, s, len);
+ jso->c_string.idata[len] = '\0';
+ return &jso->base;
}
-struct json_object* json_object_new_string_len(const char *s, int len)
+struct json_object *json_object_new_string(const char *s)
{
- char *dstbuf;
- struct json_object *jso = json_object_new(json_type_string);
- if (!jso)
- return NULL;
- jso->_delete = &json_object_string_delete;
- jso->_to_json_string = &json_object_string_to_json_string;
- if(len < LEN_DIRECT_STRING_DATA) {
- dstbuf = jso->o.c_string.str.data;
- } else {
- jso->o.c_string.str.ptr = (char*)malloc(len + 1);
- if (!jso->o.c_string.str.ptr)
- {
- json_object_generic_delete(jso);
- errno = ENOMEM;
- return NULL;
- }
- dstbuf = jso->o.c_string.str.ptr;
- }
- memcpy(dstbuf, (const void *)s, len);
- dstbuf[len] = '\0';
- jso->o.c_string.len = len;
- return jso;
+ return _json_object_new_string(s, strlen(s));
}
-const char* json_object_get_string(struct json_object *jso)
+struct json_object *json_object_new_string_len(const char *s, const int len)
+{
+ return _json_object_new_string(s, len);
+}
+
+const char *json_object_get_string(struct json_object *jso)
{
if (!jso)
return NULL;
- switch(jso->o_type)
+ switch (jso->o_type)
{
- case json_type_string:
- return get_string_component(jso);
- default:
- return json_object_to_json_string(jso);
+ case json_type_string: return get_string_component(jso);
+ default: return json_object_to_json_string(jso);
}
}
-
int json_object_get_string_len(const struct json_object *jso)
{
+ ssize_t len;
if (!jso)
return 0;
- switch(jso->o_type)
+ switch (jso->o_type)
{
case json_type_string:
- return jso->o.c_string.len;
- default:
- return 0;
+ {
+ len = JC_STRING_C(jso)->len;
+ return (len < 0) ? -(ssize_t)len : len;
+ }
+ default: return 0;
}
}
-int json_object_set_string(json_object* jso, const char* s) {
- return json_object_set_string_len(jso, s, (int)(strlen(s)));
-}
+static int _json_object_set_string_len(json_object *jso, const char *s, size_t len)
+{
+ char *dstbuf;
+ ssize_t curlen;
+ ssize_t newlen;
+ if (jso == NULL || jso->o_type != json_type_string)
+ return 0;
-int json_object_set_string_len(json_object* jso, const char* s, int len){
- char *dstbuf;
- if (jso==NULL || jso->o_type!=json_type_string) return 0;
- if (leno.c_string.str.data;
- if (jso->o.c_string.len>=LEN_DIRECT_STRING_DATA) free(jso->o.c_string.str.ptr);
- } else {
- dstbuf=(char *)malloc(len+1);
- if (dstbuf==NULL) return 0;
- if (jso->o.c_string.len>=LEN_DIRECT_STRING_DATA) free(jso->o.c_string.str.ptr);
- jso->o.c_string.str.ptr=dstbuf;
+ if (len >= SSIZE_T_MAX - 1)
+ // jso->len is a signed ssize_t, so it can't hold the
+ // full size_t range.
+ return 0;
+
+ dstbuf = get_string_component_mutable(jso);
+ curlen = JC_STRING(jso)->len;
+ if (curlen < 0)
+ curlen = -curlen;
+ newlen = len;
+
+ if ((ssize_t)len > curlen)
+ {
+ // We have no way to return the new ptr from realloc(jso, newlen)
+ // and we have no way of knowing whether there's extra room available
+ // so we need to stuff a pointer in to pdata :(
+ dstbuf = (char *)malloc(len + 1);
+ if (dstbuf == NULL)
+ return 0;
+ if (JC_STRING(jso)->len < 0)
+ free(JC_STRING(jso)->c_string.pdata);
+ JC_STRING(jso)->c_string.pdata = dstbuf;
+ newlen = -(ssize_t)len;
+ }
+ else if (JC_STRING(jso)->len < 0)
+ {
+ // We've got enough room in the separate allocated buffer,
+ // so use it as-is and continue to indicate that pdata is used.
+ newlen = -(ssize_t)len;
}
- jso->o.c_string.len=len;
+
memcpy(dstbuf, (const void *)s, len);
dstbuf[len] = '\0';
- return 1;
+ JC_STRING(jso)->len = newlen;
+ return 1;
+}
+
+int json_object_set_string(json_object *jso, const char *s)
+{
+ return _json_object_set_string_len(jso, s, strlen(s));
+}
+
+int json_object_set_string_len(json_object *jso, const char *s, int len)
+{
+ return _json_object_set_string_len(jso, s, len);
}
/* json_object_array */
-static int json_object_array_to_json_string(struct json_object* jso,
- struct printbuf *pb,
- int level,
+static int json_object_array_to_json_string(struct json_object *jso, struct printbuf *pb, int level,
int flags)
{
int had_children = 0;
@@ -1114,7 +1387,7 @@
printbuf_strappend(pb, "[");
if (flags & JSON_C_TO_STRING_PRETTY)
printbuf_strappend(pb, "\n");
- for(ii=0; ii < json_object_array_length(jso); ii++)
+ for (ii = 0; ii < json_object_array_length(jso); ii++)
{
struct json_object *val;
if (had_children)
@@ -1124,85 +1397,82 @@
printbuf_strappend(pb, "\n");
}
had_children = 1;
- if (flags & JSON_C_TO_STRING_SPACED)
+ if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
printbuf_strappend(pb, " ");
indent(pb, level + 1, flags);
val = json_object_array_get_idx(jso, ii);
- if(val == NULL)
+ if (val == NULL)
printbuf_strappend(pb, "null");
- else
- if (val->_to_json_string(val, pb, level+1, flags) < 0)
- return -1;
+ else if (val->_to_json_string(val, pb, level + 1, flags) < 0)
+ return -1;
}
if (flags & JSON_C_TO_STRING_PRETTY)
{
if (had_children)
printbuf_strappend(pb, "\n");
- indent(pb,level,flags);
+ indent(pb, level, flags);
}
- if (flags & JSON_C_TO_STRING_SPACED)
+ if (flags & JSON_C_TO_STRING_SPACED && !(flags & JSON_C_TO_STRING_PRETTY))
return printbuf_strappend(pb, " ]");
return printbuf_strappend(pb, "]");
}
static void json_object_array_entry_free(void *data)
{
- json_object_put((struct json_object*)data);
+ json_object_put((struct json_object *)data);
}
-static void json_object_array_delete(struct json_object* jso)
+static void json_object_array_delete(struct json_object *jso)
{
- array_list_free(jso->o.c_array);
+ array_list_free(JC_ARRAY(jso)->c_array);
json_object_generic_delete(jso);
}
-struct json_object* json_object_new_array(void)
+struct json_object *json_object_new_array(void)
{
- struct json_object *jso = json_object_new(json_type_array);
+ return json_object_new_array_ext(ARRAY_LIST_DEFAULT_SIZE);
+}
+struct json_object *json_object_new_array_ext(int initial_size)
+{
+ struct json_object_array *jso = JSON_OBJECT_NEW(array);
if (!jso)
return NULL;
- jso->_delete = &json_object_array_delete;
- jso->_to_json_string = &json_object_array_to_json_string;
- jso->o.c_array = array_list_new(&json_object_array_entry_free);
- if(jso->o.c_array == NULL)
+ jso->c_array = array_list_new2(&json_object_array_entry_free, initial_size);
+ if (jso->c_array == NULL)
{
- free(jso);
- return NULL;
+ free(jso);
+ return NULL;
}
- return jso;
+ return &jso->base;
}
-struct array_list* json_object_get_array(const struct json_object *jso)
+struct array_list *json_object_get_array(const struct json_object *jso)
{
if (!jso)
return NULL;
- switch(jso->o_type)
+ switch (jso->o_type)
{
- case json_type_array:
- return jso->o.c_array;
- default:
- return NULL;
+ case json_type_array: return JC_ARRAY_C(jso)->c_array;
+ default: return NULL;
}
}
-void json_object_array_sort(struct json_object *jso,
- int(*sort_fn)(const void *, const void *))
+void json_object_array_sort(struct json_object *jso, int (*sort_fn)(const void *, const void *))
{
assert(json_object_get_type(jso) == json_type_array);
- array_list_sort(jso->o.c_array, sort_fn);
+ array_list_sort(JC_ARRAY(jso)->c_array, sort_fn);
}
-struct json_object* json_object_array_bsearch(
- const struct json_object *key,
- const struct json_object *jso,
- int (*sort_fn)(const void *, const void *))
+struct json_object *json_object_array_bsearch(const struct json_object *key,
+ const struct json_object *jso,
+ int (*sort_fn)(const void *, const void *))
{
struct json_object **result;
assert(json_object_get_type(jso) == json_type_array);
- result = (struct json_object **)array_list_bsearch(
- (const void **)(void *)&key, jso->o.c_array, sort_fn);
+ result = (struct json_object **)array_list_bsearch((const void **)(void *)&key,
+ JC_ARRAY_C(jso)->c_array, sort_fn);
if (!result)
return NULL;
@@ -1212,37 +1482,34 @@
size_t json_object_array_length(const struct json_object *jso)
{
assert(json_object_get_type(jso) == json_type_array);
- return array_list_length(jso->o.c_array);
+ return array_list_length(JC_ARRAY_C(jso)->c_array);
}
-int json_object_array_add(struct json_object *jso,struct json_object *val)
+int json_object_array_add(struct json_object *jso, struct json_object *val)
{
assert(json_object_get_type(jso) == json_type_array);
- return array_list_add(jso->o.c_array, val);
+ return array_list_add(JC_ARRAY(jso)->c_array, val);
}
-int json_object_array_put_idx(struct json_object *jso, size_t idx,
- struct json_object *val)
+int json_object_array_put_idx(struct json_object *jso, size_t idx, struct json_object *val)
{
assert(json_object_get_type(jso) == json_type_array);
- return array_list_put_idx(jso->o.c_array, idx, val);
+ return array_list_put_idx(JC_ARRAY(jso)->c_array, idx, val);
}
int json_object_array_del_idx(struct json_object *jso, size_t idx, size_t count)
{
assert(json_object_get_type(jso) == json_type_array);
- return array_list_del_idx(jso->o.c_array, idx, count);
+ return array_list_del_idx(JC_ARRAY(jso)->c_array, idx, count);
}
-struct json_object* json_object_array_get_idx(const struct json_object *jso,
- size_t idx)
+struct json_object *json_object_array_get_idx(const struct json_object *jso, size_t idx)
{
assert(json_object_get_type(jso) == json_type_array);
- return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
+ return (struct json_object *)array_list_get_idx(JC_ARRAY_C(jso)->c_array, idx);
}
-static int json_array_equal(struct json_object* jso1,
- struct json_object* jso2)
+static int json_array_equal(struct json_object *jso1, struct json_object *jso2)
{
size_t len, i;
@@ -1250,16 +1517,28 @@
if (len != json_object_array_length(jso2))
return 0;
- for (i = 0; i < len; i++) {
+ for (i = 0; i < len; i++)
+ {
if (!json_object_equal(json_object_array_get_idx(jso1, i),
- json_object_array_get_idx(jso2, i)))
+ json_object_array_get_idx(jso2, i)))
return 0;
}
return 1;
}
-static int json_object_all_values_equal(struct json_object* jso1,
- struct json_object* jso2)
+int json_object_array_shrink(struct json_object *jso, int empty_slots)
+{
+ if (empty_slots < 0)
+ json_abort("json_object_array_shrink called with negative empty_slots");
+ return array_list_shrink(JC_ARRAY(jso)->c_array, empty_slots);
+}
+
+struct json_object *json_object_new_null(void)
+{
+ return NULL;
+}
+
+static int json_object_all_values_equal(struct json_object *jso1, struct json_object *jso2)
{
struct json_object_iter iter;
struct json_object *sub;
@@ -1267,25 +1546,27 @@
assert(json_object_get_type(jso1) == json_type_object);
assert(json_object_get_type(jso2) == json_type_object);
/* Iterate over jso1 keys and see if they exist and are equal in jso2 */
- json_object_object_foreachC(jso1, iter) {
- if (!lh_table_lookup_ex(jso2->o.c_object, (void*)iter.key,
- (void**)(void *)&sub))
+ json_object_object_foreachC(jso1, iter)
+ {
+ if (!lh_table_lookup_ex(JC_OBJECT(jso2)->c_object, (void *)iter.key,
+ (void **)(void *)&sub))
return 0;
if (!json_object_equal(iter.val, sub))
return 0;
- }
+ }
/* Iterate over jso2 keys to see if any exist that are not in jso1 */
- json_object_object_foreachC(jso2, iter) {
- if (!lh_table_lookup_ex(jso1->o.c_object, (void*)iter.key,
- (void**)(void *)&sub))
+ json_object_object_foreachC(jso2, iter)
+ {
+ if (!lh_table_lookup_ex(JC_OBJECT(jso1)->c_object, (void *)iter.key,
+ (void **)(void *)&sub))
return 0;
- }
+ }
return 1;
}
-int json_object_equal(struct json_object* jso1, struct json_object* jso2)
+int json_object_equal(struct json_object *jso1, struct json_object *jso2)
{
if (jso1 == jso2)
return 1;
@@ -1296,30 +1577,44 @@
if (jso1->o_type != jso2->o_type)
return 0;
- switch(jso1->o_type) {
- case json_type_boolean:
- return (jso1->o.c_boolean == jso2->o.c_boolean);
+ switch (jso1->o_type)
+ {
+ case json_type_boolean: return (JC_BOOL(jso1)->c_boolean == JC_BOOL(jso2)->c_boolean);
- case json_type_double:
- return (jso1->o.c_double == jso2->o.c_double);
+ case json_type_double: return (JC_DOUBLE(jso1)->c_double == JC_DOUBLE(jso2)->c_double);
- case json_type_int:
- return (jso1->o.c_int64 == jso2->o.c_int64);
+ case json_type_int:
+ {
+ struct json_object_int *int1 = JC_INT(jso1);
+ struct json_object_int *int2 = JC_INT(jso2);
+ if (int1->cint_type == json_object_int_type_int64)
+ {
+ if (int2->cint_type == json_object_int_type_int64)
+ return (int1->cint.c_int64 == int2->cint.c_int64);
+ if (int1->cint.c_int64 < 0)
+ return 0;
+ return ((uint64_t)int1->cint.c_int64 == int2->cint.c_uint64);
+ }
+ // else jso1 is a uint64
+ if (int2->cint_type == json_object_int_type_uint64)
+ return (int1->cint.c_uint64 == int2->cint.c_uint64);
+ if (int2->cint.c_int64 < 0)
+ return 0;
+ return (int1->cint.c_uint64 == (uint64_t)int2->cint.c_int64);
+ }
- case json_type_string:
- return (jso1->o.c_string.len == jso2->o.c_string.len &&
- memcmp(get_string_component(jso1),
- get_string_component(jso2),
- jso1->o.c_string.len) == 0);
+ case json_type_string:
+ {
+ return (json_object_get_string_len(jso1) == json_object_get_string_len(jso2) &&
+ memcmp(get_string_component(jso1), get_string_component(jso2),
+ json_object_get_string_len(jso1)) == 0);
+ }
- case json_type_object:
- return json_object_all_values_equal(jso1, jso2);
+ case json_type_object: return json_object_all_values_equal(jso1, jso2);
- case json_type_array:
- return json_array_equal(jso1, jso2);
+ case json_type_array: return json_array_equal(jso1, jso2);
- case json_type_null:
- return 1;
+ case json_type_null: return 1;
};
return 0;
@@ -1330,21 +1625,23 @@
if (!src->_userdata && !src->_user_delete)
return 0;
- if (dst->_to_json_string == json_object_userdata_to_json_string)
+ if (dst->_to_json_string == json_object_userdata_to_json_string ||
+ dst->_to_json_string == _json_object_userdata_to_json_string)
{
dst->_userdata = strdup(src->_userdata);
}
// else if ... other supported serializers ...
else
{
- _json_c_set_last_err("json_object_deep_copy: unable to copy unknown serializer data: %p\n", dst->_to_json_string);
+ _json_c_set_last_err(
+ "json_object_deep_copy: unable to copy unknown serializer data: %p\n",
+ (void *)dst->_to_json_string);
return -1;
}
dst->_user_delete = src->_user_delete;
return 0;
}
-
/**
* The default shallow copy implementation. Simply creates a new object of the same
* type but does *not* copy over _userdata nor retain any custom serializer.
@@ -1353,39 +1650,39 @@
*
* This always returns -1 or 1. It will never return 2 since it does not copy the serializer.
*/
-int json_c_shallow_copy_default(json_object *src, json_object *parent, const char *key, size_t index, json_object **dst)
+int json_c_shallow_copy_default(json_object *src, json_object *parent, const char *key,
+ size_t index, json_object **dst)
{
- switch (src->o_type) {
- case json_type_boolean:
- *dst = json_object_new_boolean(src->o.c_boolean);
- break;
+ switch (src->o_type)
+ {
+ case json_type_boolean: *dst = json_object_new_boolean(JC_BOOL(src)->c_boolean); break;
- case json_type_double:
- *dst = json_object_new_double(src->o.c_double);
- break;
+ case json_type_double: *dst = json_object_new_double(JC_DOUBLE(src)->c_double); break;
case json_type_int:
- *dst = json_object_new_int64(src->o.c_int64);
+ switch (JC_INT(src)->cint_type)
+ {
+ case json_object_int_type_int64:
+ *dst = json_object_new_int64(JC_INT(src)->cint.c_int64);
+ break;
+ case json_object_int_type_uint64:
+ *dst = json_object_new_uint64(JC_INT(src)->cint.c_uint64);
+ break;
+ default: json_abort("invalid cint_type");
+ }
break;
- case json_type_string:
- *dst = json_object_new_string(get_string_component(src));
- break;
+ case json_type_string: *dst = json_object_new_string(get_string_component(src)); break;
- case json_type_object:
- *dst = json_object_new_object();
- break;
+ case json_type_object: *dst = json_object_new_object(); break;
- case json_type_array:
- *dst = json_object_new_array();
- break;
+ case json_type_array: *dst = json_object_new_array(); break;
- default:
- errno = EINVAL;
- return -1;
+ default: errno = EINVAL; return -1;
}
- if (!*dst) {
+ if (!*dst)
+ {
errno = ENOMEM;
return -1;
}
@@ -1400,7 +1697,10 @@
*
* Note: caller is responsible for freeing *dst if this fails and returns -1.
*/
-static int json_object_deep_copy_recursive(struct json_object *src, struct json_object *parent, const char *key_in_parent, size_t index_in_parent, struct json_object **dst, json_c_shallow_copy_fn *shallow_copy)
+static int json_object_deep_copy_recursive(struct json_object *src, struct json_object *parent,
+ const char *key_in_parent, size_t index_in_parent,
+ struct json_object **dst,
+ json_c_shallow_copy_fn *shallow_copy)
{
struct json_object_iter iter;
size_t src_array_len, ii;
@@ -1415,14 +1715,17 @@
}
assert(*dst != NULL);
- switch (src->o_type) {
+ switch (src->o_type)
+ {
case json_type_object:
- json_object_object_foreachC(src, iter) {
+ json_object_object_foreachC(src, iter)
+ {
struct json_object *jso = NULL;
/* This handles the `json_type_null` case */
if (!iter.val)
jso = NULL;
- else if (json_object_deep_copy_recursive(iter.val, src, iter.key, -1, &jso, shallow_copy) < 0)
+ else if (json_object_deep_copy_recursive(iter.val, src, iter.key, -1, &jso,
+ shallow_copy) < 0)
{
json_object_put(jso);
return -1;
@@ -1438,13 +1741,15 @@
case json_type_array:
src_array_len = json_object_array_length(src);
- for (ii = 0; ii < src_array_len; ii++) {
+ for (ii = 0; ii < src_array_len; ii++)
+ {
struct json_object *jso = NULL;
struct json_object *jso1 = json_object_array_get_idx(src, ii);
/* This handles the `json_type_null` case */
if (!jso1)
jso = NULL;
- else if (json_object_deep_copy_recursive(jso1, src, NULL, ii, &jso, shallow_copy) < 0)
+ else if (json_object_deep_copy_recursive(jso1, src, NULL, ii, &jso,
+ shallow_copy) < 0)
{
json_object_put(jso);
return -1;
@@ -1469,12 +1774,14 @@
return 0;
}
-int json_object_deep_copy(struct json_object *src, struct json_object **dst, json_c_shallow_copy_fn *shallow_copy)
+int json_object_deep_copy(struct json_object *src, struct json_object **dst,
+ json_c_shallow_copy_fn *shallow_copy)
{
int rc;
/* Check if arguments are sane ; *dst must not point to a non-NULL object */
- if (!src || !dst || *dst) {
+ if (!src || !dst || *dst)
+ {
errno = EINVAL;
return -1;
}
@@ -1483,7 +1790,8 @@
shallow_copy = json_c_shallow_copy_default;
rc = json_object_deep_copy_recursive(src, NULL, NULL, -1, dst, shallow_copy);
- if (rc < 0) {
+ if (rc < 0)
+ {
json_object_put(*dst);
*dst = NULL;
}
@@ -1491,3 +1799,9 @@
return rc;
}
+static void json_abort(const char *message)
+{
+ if (message != NULL)
+ fprintf(stderr, "json-c aborts with error: %s\n", message);
+ abort();
+}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_object.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_object.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_object.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_object.h 2022-04-15 07:49:21.000000000 +0000
@@ -18,31 +18,17 @@
#define _json_object_h_
#ifdef __GNUC__
-#define THIS_FUNCTION_IS_DEPRECATED(func) func __attribute__ ((deprecated))
-#elif defined(_MSC_VER)
-#define THIS_FUNCTION_IS_DEPRECATED(func) __declspec(deprecated) func
-#elif defined(__clang__)
-#define THIS_FUNCTION_IS_DEPRECATED(func) func __deprecated
-#else
-#define THIS_FUNCTION_IS_DEPRECATED(func) func
-#endif
-
-#ifdef __GNUC__
#define JSON_C_CONST_FUNCTION(func) func __attribute__((const))
#else
#define JSON_C_CONST_FUNCTION(func) func
#endif
-#if defined(_MSC_VER)
-#define JSON_EXPORT __declspec(dllexport)
-#else
-#define JSON_EXPORT extern
-#endif
-
-#include
#include "json_inttypes.h"
+#include "json_types.h"
#include "printbuf.h"
+#include
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -54,13 +40,13 @@
* json_object_to_file_ext() functions which causes the output
* to have no extra whitespace or formatting applied.
*/
-#define JSON_C_TO_STRING_PLAIN 0
+#define JSON_C_TO_STRING_PLAIN 0
/**
* A flag for the json_object_to_json_string_ext() and
* json_object_to_file_ext() functions which causes the output to have
* minimal whitespace inserted to make things slightly more readable.
*/
-#define JSON_C_TO_STRING_SPACED (1<<0)
+#define JSON_C_TO_STRING_SPACED (1 << 0)
/**
* A flag for the json_object_to_json_string_ext() and
* json_object_to_file_ext() functions which causes
@@ -69,7 +55,7 @@
* See the "Two Space Tab" option at http://jsonformatter.curiousconcept.com/
* for an example of the format.
*/
-#define JSON_C_TO_STRING_PRETTY (1<<1)
+#define JSON_C_TO_STRING_PRETTY (1 << 1)
/**
* A flag for the json_object_to_json_string_ext() and
* json_object_to_file_ext() functions which causes
@@ -77,28 +63,28 @@
*
* Instead of a "Two Space Tab" this gives a single tab character.
*/
-#define JSON_C_TO_STRING_PRETTY_TAB (1<<3)
+#define JSON_C_TO_STRING_PRETTY_TAB (1 << 3)
/**
* A flag to drop trailing zero for float values
*/
-#define JSON_C_TO_STRING_NOZERO (1<<2)
+#define JSON_C_TO_STRING_NOZERO (1 << 2)
/**
* Don't escape forward slashes.
*/
-#define JSON_C_TO_STRING_NOSLASHESCAPE (1<<4)
+#define JSON_C_TO_STRING_NOSLASHESCAPE (1 << 4)
/**
* A flag for the json_object_object_add_ex function which
* causes the value to be added without a check if it already exists.
- * Note: it is the responsibilty of the caller to ensure that no
+ * Note: it is the responsibility of the caller to ensure that no
* key is added multiple times. If this is done, results are
* unpredictable. While this option is somewhat dangerous, it
* permits potentially large performance savings in code that
* knows for sure the key values are unique (e.g. because the
* code adds a well-known set of constant key values).
*/
-#define JSON_C_OBJECT_ADD_KEY_IS_NEW (1<<1)
+#define JSON_C_OBJECT_ADD_KEY_IS_NEW (1 << 1)
/**
* A flag for the json_object_object_add_ex function which
* flags the key as being constant memory. This means that
@@ -116,13 +102,7 @@
* json_object_object_add_ex(obj, "ip", json,
* JSON_C_OBJECT_KEY_IS_CONSTANT);
*/
-#define JSON_C_OBJECT_KEY_IS_CONSTANT (1<<2)
-
-#undef FALSE
-#define FALSE ((json_bool)0)
-
-#undef TRUE
-#define TRUE ((json_bool)1)
+#define JSON_C_OBJECT_KEY_IS_CONSTANT (1 << 2)
/**
* Set the global value of an option, which will apply to all
@@ -140,68 +120,46 @@
*/
#define JSON_C_OPTION_THREAD (1)
-/**
- * A structure to use with json_object_object_foreachC() loops.
- * Contains key, val and entry members.
- */
-struct json_object_iter
-{
- char *key;
- struct json_object *val;
- struct lh_entry *entry;
-};
-typedef struct json_object_iter json_object_iter;
-
-typedef int json_bool;
-
-/**
- * @brief The core type for all type of JSON objects handled by json-c
- */
-typedef struct json_object json_object;
-
-/**
- * Type of custom user delete functions. See json_object_set_serializer.
- */
-typedef void (json_object_delete_fn)(struct json_object *jso, void *userdata);
-
-/**
- * Type of a custom serialization function. See json_object_set_serializer.
- */
-typedef int (json_object_to_json_string_fn)(struct json_object *jso,
- struct printbuf *pb,
- int level,
- int flags);
-
-/* supported object types */
-
-typedef enum json_type {
- /* If you change this, be sure to update json_type_to_name() too */
- json_type_null,
- json_type_boolean,
- json_type_double,
- json_type_int,
- json_type_object,
- json_type_array,
- json_type_string
-} json_type;
-
/* reference counting functions */
/**
- * Increment the reference count of json_object, thereby grabbing shared
- * ownership of obj.
+ * Increment the reference count of json_object, thereby taking ownership of it.
*
- * @param obj the json_object instance
+ * Cases where you might need to increase the refcount include:
+ * - Using an object field or array index (retrieved through
+ * `json_object_object_get()` or `json_object_array_get_idx()`)
+ * beyond the lifetime of the parent object.
+ * - Detaching an object field or array index from its parent object
+ * (using `json_object_object_del()` or `json_object_array_del_idx()`)
+ * - Sharing a json_object with multiple (not necesarily parallel) threads
+ * of execution that all expect to free it (with `json_object_put()`) when
+ * they're done.
+ *
+ * @param obj the json_object instance
+ * @see json_object_put()
+ * @see json_object_object_get()
+ * @see json_object_array_get_idx()
*/
-JSON_EXPORT struct json_object* json_object_get(struct json_object *obj);
+JSON_EXPORT struct json_object *json_object_get(struct json_object *obj);
/**
* Decrement the reference count of json_object and free if it reaches zero.
+ *
* You must have ownership of obj prior to doing this or you will cause an
- * imbalance in the reference count.
+ * imbalance in the reference count, leading to a classic use-after-free bug.
+ * In particular, you normally do not need to call `json_object_put()` on the
+ * json_object returned by `json_object_object_get()` or `json_object_array_get_idx()`.
+ *
+ * Just like after calling `free()` on a block of memory, you must not use
+ * `obj` after calling `json_object_put()` on it or any object that it
+ * is a member of (unless you know you've called `json_object_get(obj)` to
+ * explicitly increment the refcount).
+ *
+ * NULL may be passed, which which case this is a no-op.
*
* @param obj the json_object instance
* @returns 1 if the object was freed.
+ * @see json_object_get()
*/
JSON_EXPORT int json_object_put(struct json_object *obj);
@@ -235,7 +193,6 @@
*/
JSON_EXPORT enum json_type json_object_get_type(const struct json_object *obj);
-
/** Stringify object to json format.
* Equivalent to json_object_to_json_string_ext(obj, JSON_C_TO_STRING_SPACED)
* The pointer you get is an internal of your json object. You don't
@@ -245,7 +202,7 @@
* @param obj the json_object instance
* @returns a string in JSON format
*/
-JSON_EXPORT const char* json_object_to_json_string(struct json_object *obj);
+JSON_EXPORT const char *json_object_to_json_string(struct json_object *obj);
/** Stringify object to json format
* @see json_object_to_json_string() for details on how to free string.
@@ -253,8 +210,7 @@
* @param flags formatting options, see JSON_C_TO_STRING_PRETTY and other constants
* @returns a string in JSON format
*/
-JSON_EXPORT const char* json_object_to_json_string_ext(struct json_object *obj, int
-flags);
+JSON_EXPORT const char *json_object_to_json_string_ext(struct json_object *obj, int flags);
/** Stringify object to json format
* @see json_object_to_json_string() for details on how to free string.
@@ -263,8 +219,8 @@
* @param length a pointer where, if not NULL, the length (without null) is stored
* @returns a string in JSON format and the length if not NULL
*/
-JSON_EXPORT const char* json_object_to_json_string_length(struct json_object *obj, int
-flags, size_t *length);
+JSON_EXPORT const char *json_object_to_json_string_length(struct json_object *obj, int flags,
+ size_t *length);
/**
* Returns the userdata set by json_object_set_userdata() or
@@ -272,7 +228,7 @@
*
* @param jso the object to return the userdata for
*/
-JSON_EXPORT void* json_object_get_userdata(json_object *jso);
+JSON_EXPORT void *json_object_get_userdata(json_object *jso);
/**
* Set an opaque userdata value for an object
@@ -300,7 +256,7 @@
* @param user_delete an optional function from freeing userdata
*/
JSON_EXPORT void json_object_set_userdata(json_object *jso, void *userdata,
- json_object_delete_fn *user_delete);
+ json_object_delete_fn *user_delete);
/**
* Set a custom serialization function to be used when this particular object
@@ -333,9 +289,8 @@
* @param user_delete an optional function from freeing userdata
*/
JSON_EXPORT void json_object_set_serializer(json_object *jso,
- json_object_to_json_string_fn *to_string_func,
- void *userdata,
- json_object_delete_fn *user_delete);
+ json_object_to_json_string_fn *to_string_func,
+ void *userdata, json_object_delete_fn *user_delete);
#ifdef __clang__
/*
@@ -354,7 +309,7 @@
* @param jso unused
* @param userdata the pointer that is passed to free().
*/
-json_object_delete_fn json_object_free_userdata;
+JSON_EXPORT json_object_delete_fn json_object_free_userdata;
/**
* Copy the jso->_userdata string over to pb as-is.
@@ -365,14 +320,13 @@
* @param level Ignored.
* @param flags Ignored.
*/
-json_object_to_json_string_fn json_object_userdata_to_json_string;
+JSON_EXPORT json_object_to_json_string_fn json_object_userdata_to_json_string;
#ifdef __clang__
/* } */
#pragma clang diagnostic pop
#endif
-
/* object type methods */
/** Create a new empty object with a reference count of 1. The caller of
@@ -385,18 +339,18 @@
*
* @returns a json_object of type json_type_object
*/
-JSON_EXPORT struct json_object* json_object_new_object(void);
+JSON_EXPORT struct json_object *json_object_new_object(void);
/** Get the hashtable of a json_object of type json_type_object
* @param obj the json_object instance
* @returns a linkhash
*/
-JSON_EXPORT struct lh_table* json_object_get_object(const struct json_object *obj);
+JSON_EXPORT struct lh_table *json_object_get_object(const struct json_object *obj);
/** Get the size of an object in terms of the number of fields it has.
* @param obj the json_object whose length to return
*/
-JSON_EXPORT int json_object_object_length(const struct json_object* obj);
+JSON_EXPORT int json_object_object_length(const struct json_object *obj);
/** Get the sizeof (struct json_object).
* @returns a size_t with the sizeof (struct json_object)
@@ -405,15 +359,21 @@
/** Add an object field to a json_object of type json_type_object
*
- * The reference count will *not* be incremented. This is to make adding
- * fields to objects in code more compact. If you want to retain a reference
- * to an added object, independent of the lifetime of obj, you must wrap the
- * passed object with json_object_get.
+ * The reference count of `val` will *not* be incremented, in effect
+ * transferring ownership that object to `obj`, and thus `val` will be
+ * freed when `obj` is. (i.e. through `json_object_put(obj)`)
+ *
+ * If you want to retain a reference to the added object, independent
+ * of the lifetime of obj, you must increment the refcount with
+ * `json_object_get(val)` (and later release it with json_object_put()).
+ *
+ * Since ownership transfers to `obj`, you must make sure
+ * that you do in fact have ownership over `val`. For instance,
+ * json_object_new_object() will give you ownership until you transfer it,
+ * whereas json_object_object_get() does not.
*
- * Upon calling this, the ownership of val transfers to obj. Thus you must
- * make sure that you do in fact have ownership over this object. For instance,
- * json_object_new_object will give you ownership until you transfer it,
- * whereas json_object_object_get does not.
+ * Any previous object stored under `key` in `obj` will have its refcount
+ * decremented, and be freed normally if that drops to zero.
*
* @param obj the json_object instance
* @param key the object field name (a private copy will be duplicated)
@@ -422,8 +382,8 @@
* @return On success, 0 is returned.
* On error, a negative value is returned.
*/
-JSON_EXPORT int json_object_object_add(struct json_object* obj, const char *key,
- struct json_object *val);
+JSON_EXPORT int json_object_object_add(struct json_object *obj, const char *key,
+ struct json_object *val);
/** Add an object field to a json_object of type json_type_object
*
@@ -435,20 +395,18 @@
* @param obj the json_object instance
* @param key the object field name (a private copy will be duplicated)
* @param val a json_object or NULL member to associate with the given field
- * @param opts process-modifying options. To specify multiple options, use
- * arithmetic or (OPT1|OPT2)
+ * @param opts process-modifying options. To specify multiple options, use
+ * (OPT1|OPT2)
*/
-JSON_EXPORT int json_object_object_add_ex(struct json_object* obj,
- const char *const key,
- struct json_object *const val,
- const unsigned opts);
+JSON_EXPORT int json_object_object_add_ex(struct json_object *obj, const char *const key,
+ struct json_object *const val, const unsigned opts);
/** Get the json_object associate with a given object field.
* Deprecated/discouraged: used json_object_object_get_ex instead.
*
* This returns NULL if the field is found but its value is null, or if
* the field is not found, or if obj is not a json_type_object. If you
- * need to distinguis between these cases, use json_object_object_get_ex().
+ * need to distinguish between these cases, use json_object_object_get_ex().
*
* *No* reference counts will be changed. There is no need to manually adjust
* reference counts through the json_object_put/json_object_get methods unless
@@ -464,8 +422,8 @@
* @param key the object field name
* @returns the json_object associated with the given field name
*/
-JSON_EXPORT struct json_object* json_object_object_get(const struct json_object* obj,
- const char *key);
+JSON_EXPORT struct json_object *json_object_object_get(const struct json_object *obj,
+ const char *key);
/** Get the json_object associated with a given object field.
*
@@ -485,9 +443,8 @@
* It is safe to pass a NULL value.
* @returns whether or not the key exists
*/
-JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object* obj,
- const char *key,
- struct json_object **value);
+JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object *obj, const char *key,
+ struct json_object **value);
/** Delete the given json_object field
*
@@ -498,7 +455,7 @@
* @param obj the json_object instance
* @param key the object field name
*/
-JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key);
+JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key);
/**
* Iterate through all keys and values of an object.
@@ -515,31 +472,35 @@
*/
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L
-# define json_object_object_foreach(obj,key,val) \
- char *key = NULL; \
- struct json_object *val __attribute__((__unused__)) = NULL; \
- for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \
- ({ if(entry ## key) { \
- key = (char*)lh_entry_k(entry ## key); \
- val = (struct json_object*)lh_entry_v(entry ## key); \
- entry_next ## key = entry ## key->next; \
- } ; entry ## key; }); \
- entry ## key = entry_next ## key )
+#define json_object_object_foreach(obj, key, val) \
+ char *key = NULL; \
+ struct json_object *val __attribute__((__unused__)) = NULL; \
+ for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \
+ *entry_next##key = NULL; \
+ ({ \
+ if (entry##key) \
+ { \
+ key = (char *)lh_entry_k(entry##key); \
+ val = (struct json_object *)lh_entry_v(entry##key); \
+ entry_next##key = entry##key->next; \
+ }; \
+ entry##key; \
+ }); \
+ entry##key = entry_next##key)
#else /* ANSI C or MSC */
-# define json_object_object_foreach(obj,key,val) \
- char *key = NULL;\
- struct json_object *val = NULL; \
- struct lh_entry *entry ## key; \
- struct lh_entry *entry_next ## key = NULL; \
- for(entry ## key = json_object_get_object(obj)->head; \
- (entry ## key ? ( \
- key = (char*)lh_entry_k(entry ## key), \
- val = (struct json_object*)lh_entry_v(entry ## key), \
- entry_next ## key = entry ## key->next, \
- entry ## key) : 0); \
- entry ## key = entry_next ## key)
+#define json_object_object_foreach(obj, key, val) \
+ char *key = NULL; \
+ struct json_object *val = NULL; \
+ struct lh_entry *entry##key; \
+ struct lh_entry *entry_next##key = NULL; \
+ for (entry##key = json_object_get_object(obj)->head; \
+ (entry##key ? (key = (char *)lh_entry_k(entry##key), \
+ val = (struct json_object *)lh_entry_v(entry##key), \
+ entry_next##key = entry##key->next, entry##key) \
+ : 0); \
+ entry##key = entry_next##key)
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */
@@ -547,23 +508,38 @@
* @param obj the json_object instance
* @param iter the object iterator, use type json_object_iter
*/
-#define json_object_object_foreachC(obj,iter) \
- for(iter.entry = json_object_get_object(obj)->head; \
- (iter.entry ? (iter.key = (char*)lh_entry_k(iter.entry), iter.val = (struct json_object*)lh_entry_v(iter.entry), iter.entry) : 0); \
- iter.entry = iter.entry->next)
+#define json_object_object_foreachC(obj, iter) \
+ for (iter.entry = json_object_get_object(obj)->head; \
+ (iter.entry ? (iter.key = (char *)lh_entry_k(iter.entry), \
+ iter.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \
+ : 0); \
+ iter.entry = iter.entry->next)
/* Array type methods */
/** Create a new empty json_object of type json_type_array
+ * with 32 slots allocated.
+ * If you know the array size you'll need ahead of time, use
+ * json_object_new_array_ext() instead.
+ * @see json_object_new_array_ext()
+ * @see json_object_array_shrink()
+ * @returns a json_object of type json_type_array
+ */
+JSON_EXPORT struct json_object *json_object_new_array(void);
+
+/** Create a new empty json_object of type json_type_array
+ * with the desired number of slots allocated.
+ * @see json_object_array_shrink()
+ * @param initial_size the number of slots to allocate
* @returns a json_object of type json_type_array
*/
-JSON_EXPORT struct json_object* json_object_new_array(void);
+JSON_EXPORT struct json_object *json_object_new_array_ext(int initial_size);
/** Get the arraylist of a json_object of type json_type_array
* @param obj the json_object instance
* @returns an arraylist
*/
-JSON_EXPORT struct array_list* json_object_get_array(const struct json_object *obj);
+JSON_EXPORT struct array_list *json_object_get_array(const struct json_object *obj);
/** Get the length of a json_object of type json_type_array
* @param obj the json_object instance
@@ -579,7 +555,8 @@
* @param jso the json_object instance
* @param sort_fn a sorting function
*/
-JSON_EXPORT void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *));
+JSON_EXPORT void json_object_array_sort(struct json_object *jso,
+ int (*sort_fn)(const void *, const void *));
/** Binary search a sorted array for a specified key object.
*
@@ -595,10 +572,9 @@
*
* @return the wanted json_object instance
*/
-JSON_EXPORT struct json_object* json_object_array_bsearch(
- const struct json_object *key,
- const struct json_object *jso,
- int (*sort_fn)(const void *, const void *));
+JSON_EXPORT struct json_object *
+json_object_array_bsearch(const struct json_object *key, const struct json_object *jso,
+ int (*sort_fn)(const void *, const void *));
/** Add an element to the end of a json_object of type json_type_array
*
@@ -609,8 +585,7 @@
* @param obj the json_object instance
* @param val the json_object to be added
*/
-JSON_EXPORT int json_object_array_add(struct json_object *obj,
- struct json_object *val);
+JSON_EXPORT int json_object_array_add(struct json_object *obj, struct json_object *val);
/** Insert or replace an element at a specified index in an array (a json_object of type json_type_array)
*
@@ -628,20 +603,28 @@
* @param val the json_object to be added
*/
JSON_EXPORT int json_object_array_put_idx(struct json_object *obj, size_t idx,
- struct json_object *val);
+ struct json_object *val);
-/** Get the element at specificed index of the array (a json_object of type json_type_array)
+/** Get the element at specified index of array `obj` (which must be a json_object of type json_type_array)
+ *
+ * *No* reference counts will be changed, and ownership of the returned
+ * object remains with `obj`. See json_object_object_get() for additional
+ * implications of this behavior.
+ *
+ * Calling this with anything other than a json_type_array will trigger
+ * an assert.
+ *
* @param obj the json_object instance
* @param idx the index to get the element at
* @returns the json_object at the specified index (or NULL)
*/
-JSON_EXPORT struct json_object* json_object_array_get_idx(const struct json_object *obj,
- size_t idx);
+JSON_EXPORT struct json_object *json_object_array_get_idx(const struct json_object *obj,
+ size_t idx);
/** Delete an elements from a specified index in an array (a json_object of type json_type_array)
*
* The reference count will be decremented for each of the deleted objects. If there
- * are no more owners of an element that is being deleted, then the value is
+ * are no more owners of an element that is being deleted, then the value is
* freed. Otherwise, the reference to the value will remain in memory.
*
* @param obj the json_object instance
@@ -651,40 +634,47 @@
*/
JSON_EXPORT int json_object_array_del_idx(struct json_object *obj, size_t idx, size_t count);
+/**
+ * Shrink the internal memory allocation of the array to just
+ * enough to fit the number of elements in it, plus empty_slots.
+ *
+ * @param jso the json_object instance, must be json_type_array
+ * @param empty_slots the number of empty slots to leave allocated
+ */
+JSON_EXPORT int json_object_array_shrink(struct json_object *jso, int empty_slots);
+
/* json_bool type methods */
/** Create a new empty json_object of type json_type_boolean
- * @param b a json_bool TRUE or FALSE (1 or 0)
+ * @param b a json_bool 1 or 0
* @returns a json_object of type json_type_boolean
*/
-JSON_EXPORT struct json_object* json_object_new_boolean(json_bool b);
+JSON_EXPORT struct json_object *json_object_new_boolean(json_bool b);
/** Get the json_bool value of a json_object
*
* The type is coerced to a json_bool if the passed object is not a json_bool.
- * integer and double objects will return FALSE if there value is zero
- * or TRUE otherwise. If the passed object is a string it will return
- * TRUE if it has a non zero length. If any other object type is passed
- * TRUE will be returned if the object is not NULL.
+ * integer and double objects will return 0 if there value is zero
+ * or 1 otherwise. If the passed object is a string it will return
+ * 1 if it has a non zero length. If any other object type is passed
+ * 1 will be returned if the object is not NULL.
*
* @param obj the json_object instance
* @returns a json_bool
*/
JSON_EXPORT json_bool json_object_get_boolean(const struct json_object *obj);
-
/** Set the json_bool value of a json_object
- *
- * The type of obj is checked to be a json_type_boolean and 0 is returned
+ *
+ * The type of obj is checked to be a json_type_boolean and 0 is returned
* if it is not without any further actions. If type of obj is json_type_boolean
- * the obect value is chaned to new_value
+ * the object value is changed to new_value
*
* @param obj the json_object instance
* @param new_value the value to be set
* @returns 1 if value is set correctly, 0 otherwise
*/
-JSON_EXPORT int json_object_set_boolean(struct json_object *obj,json_bool new_value);
-
+JSON_EXPORT int json_object_set_boolean(struct json_object *obj, json_bool new_value);
/* int type methods */
@@ -694,15 +684,19 @@
* @param i the integer
* @returns a json_object of type json_type_int
*/
-JSON_EXPORT struct json_object* json_object_new_int(int32_t i);
-
+JSON_EXPORT struct json_object *json_object_new_int(int32_t i);
/** Create a new empty json_object of type json_type_int
* @param i the integer
* @returns a json_object of type json_type_int
*/
-JSON_EXPORT struct json_object* json_object_new_int64(int64_t i);
+JSON_EXPORT struct json_object *json_object_new_int64(int64_t i);
+/** Create a new empty json_object of type json_type_uint
+ * @param i the integer
+ * @returns a json_object of type json_type_uint
+ */
+JSON_EXPORT struct json_object *json_object_new_uint64(uint64_t i);
/** Get the int value of a json_object
*
@@ -721,16 +715,16 @@
JSON_EXPORT int32_t json_object_get_int(const struct json_object *obj);
/** Set the int value of a json_object
- *
- * The type of obj is checked to be a json_type_int and 0 is returned
+ *
+ * The type of obj is checked to be a json_type_int and 0 is returned
* if it is not without any further actions. If type of obj is json_type_int
- * the obect value is changed to new_value
+ * the object value is changed to new_value
*
* @param obj the json_object instance
* @param new_value the value to be set
* @returns 1 if value is set correctly, 0 otherwise
*/
-JSON_EXPORT int json_object_set_int(struct json_object *obj,int new_value);
+JSON_EXPORT int json_object_set_int(struct json_object *obj, int new_value);
/** Increment a json_type_int object by the given amount, which may be negative.
*
@@ -748,7 +742,6 @@
*/
JSON_EXPORT int json_object_int_inc(struct json_object *obj, int64_t val);
-
/** Get the int value of a json_object
*
* The type is coerced to a int64 if the passed object is not a int64.
@@ -764,18 +757,44 @@
*/
JSON_EXPORT int64_t json_object_get_int64(const struct json_object *obj);
+/** Get the uint value of a json_object
+ *
+ * The type is coerced to a uint64 if the passed object is not a uint64.
+ * double objects will return their uint64 conversion. Strings will be
+ * parsed as an uint64. If no conversion exists then 0 is returned.
+ *
+ * NOTE: Set errno to 0 directly before a call to this function to determine
+ * whether or not conversion was successful (it does not clear the value for
+ * you).
+ *
+ * @param obj the json_object instance
+ * @returns an uint64
+ */
+JSON_EXPORT uint64_t json_object_get_uint64(const struct json_object *obj);
/** Set the int64_t value of a json_object
- *
- * The type of obj is checked to be a json_type_int and 0 is returned
+ *
+ * The type of obj is checked to be a json_type_int and 0 is returned
* if it is not without any further actions. If type of obj is json_type_int
- * the obect value is chaned to new_value
+ * the object value is changed to new_value
*
* @param obj the json_object instance
* @param new_value the value to be set
* @returns 1 if value is set correctly, 0 otherwise
*/
-JSON_EXPORT int json_object_set_int64(struct json_object *obj,int64_t new_value);
+JSON_EXPORT int json_object_set_int64(struct json_object *obj, int64_t new_value);
+
+/** Set the uint64_t value of a json_object
+ *
+ * The type of obj is checked to be a json_type_uint and 0 is returned
+ * if it is not without any further actions. If type of obj is json_type_uint
+ * the object value is changed to new_value
+ *
+ * @param obj the json_object instance
+ * @param new_value the value to be set
+ * @returns 1 if value is set correctly, 0 otherwise
+ */
+JSON_EXPORT int json_object_set_uint64(struct json_object *obj, uint64_t new_value);
/* double type methods */
@@ -786,7 +805,7 @@
* @param d the double
* @returns a json_object of type json_type_double
*/
-JSON_EXPORT struct json_object* json_object_new_double(double d);
+JSON_EXPORT struct json_object *json_object_new_double(double d);
/**
* Create a new json_object of type json_type_double, using
@@ -804,7 +823,8 @@
* The userdata field is used to store the string representation, so it
* can't be used for other data if this function is used.
*
- * An equivalent sequence of calls is:
+ * A roughly equivalent sequence of calls, with the difference being that
+ * the serialization function won't be reset by json_object_set_double(), is:
* @code
* jso = json_object_new_double(d);
* json_object_set_serializer(jso, json_object_userdata_to_json_string,
@@ -814,7 +834,7 @@
* @param d the numeric value of the double.
* @param ds the string representation of the double. This will be copied.
*/
-JSON_EXPORT struct json_object* json_object_new_double_s(double d, const char *ds);
+JSON_EXPORT struct json_object *json_object_new_double_s(double d, const char *ds);
/**
* Set a global or thread-local json-c option, depending on whether
@@ -828,9 +848,8 @@
*
* @return -1 on errors, 0 on success.
*/
-int json_c_set_serialization_double_format(const char *double_format, int global_or_thread);
-
-
+JSON_EXPORT int json_c_set_serialization_double_format(const char *double_format,
+ int global_or_thread);
/** Serialize a json_object of type json_type_double to a string.
*
@@ -851,10 +870,8 @@
* @param level Ignored.
* @param flags Ignored.
*/
-JSON_EXPORT int json_object_double_to_json_string(struct json_object* jso,
- struct printbuf *pb,
- int level,
- int flags);
+JSON_EXPORT int json_object_double_to_json_string(struct json_object *jso, struct printbuf *pb,
+ int level, int flags);
/** Get the double floating point value of a json_object
*
@@ -881,20 +898,20 @@
*/
JSON_EXPORT double json_object_get_double(const struct json_object *obj);
-
/** Set the double value of a json_object
- *
- * The type of obj is checked to be a json_type_double and 0 is returned
+ *
+ * The type of obj is checked to be a json_type_double and 0 is returned
* if it is not without any further actions. If type of obj is json_type_double
- * the obect value is chaned to new_value
+ * the object value is changed to new_value
+ *
+ * If the object was created with json_object_new_double_s(), the serialization
+ * function is reset to the default and the cached serialized value is cleared.
*
* @param obj the json_object instance
* @param new_value the value to be set
* @returns 1 if value is set correctly, 0 otherwise
*/
-JSON_EXPORT int json_object_set_double(struct json_object *obj,double new_value);
-
-
+JSON_EXPORT int json_object_set_double(struct json_object *obj, double new_value);
/* string type methods */
@@ -904,10 +921,21 @@
*
* @param s the string
* @returns a json_object of type json_type_string
+ * @see json_object_new_string_len()
*/
-JSON_EXPORT struct json_object* json_object_new_string(const char *s);
+JSON_EXPORT struct json_object *json_object_new_string(const char *s);
-JSON_EXPORT struct json_object* json_object_new_string_len(const char *s, int len);
+/** Create a new empty json_object of type json_type_string and allocate
+ * len characters for the new string.
+ *
+ * A copy of the string is made and the memory is managed by the json_object
+ *
+ * @param s the string
+ * @param len max length of the new string
+ * @returns a json_object of type json_type_string
+ * @see json_object_new_string()
+ */
+JSON_EXPORT struct json_object *json_object_new_string_len(const char *s, const int len);
/** Get the string value of a json_object
*
@@ -925,7 +953,7 @@
* @param obj the json_object instance
* @returns a string or NULL
*/
-JSON_EXPORT const char* json_object_get_string(struct json_object *obj);
+JSON_EXPORT const char *json_object_get_string(struct json_object *obj);
/** Get the string length of a json_object
*
@@ -937,25 +965,30 @@
*/
JSON_EXPORT int json_object_get_string_len(const struct json_object *obj);
-
/** Set the string value of a json_object with zero terminated strings
* equivalent to json_object_set_string_len (obj, new_value, strlen(new_value))
* @returns 1 if value is set correctly, 0 otherwise
*/
-JSON_EXPORT int json_object_set_string(json_object* obj, const char* new_value);
+JSON_EXPORT int json_object_set_string(json_object *obj, const char *new_value);
/** Set the string value of a json_object str
- *
- * The type of obj is checked to be a json_type_string and 0 is returned
+ *
+ * The type of obj is checked to be a json_type_string and 0 is returned
* if it is not without any further actions. If type of obj is json_type_string
- * the obect value is chaned to new_value
+ * the object value is changed to new_value
*
* @param obj the json_object instance
- * @param new_value the value to be set; Since string legth is given in len this need not be zero terminated
+ * @param new_value the value to be set; Since string length is given in len this need not be zero terminated
* @param len the length of new_value
* @returns 1 if value is set correctly, 0 otherwise
*/
-JSON_EXPORT int json_object_set_string_len(json_object* obj, const char* new_value, int len);
+JSON_EXPORT int json_object_set_string_len(json_object *obj, const char *new_value, int len);
+
+/** This method exists only to provide a complementary function
+ * along the lines of the other json_object_new_* functions.
+ * It always returns NULL, and it is entirely acceptable to simply use NULL directly.
+ */
+JSON_EXPORT struct json_object *json_object_new_null(void);
/** Check if two json_object's are equal
*
@@ -974,8 +1007,7 @@
* @param obj2 the second json_object instance
* @returns whether both objects are equal or not
*/
-JSON_EXPORT int json_object_equal(struct json_object *obj1,
- struct json_object *obj2);
+JSON_EXPORT int json_object_equal(struct json_object *obj1, struct json_object *obj2);
/**
* Perform a shallow copy of src into *dst as part of an overall json_object_deep_copy().
@@ -985,17 +1017,18 @@
* When shallow_copy is called *dst will be NULL, and must be non-NULL when it returns.
* src will never be NULL.
*
- * If shallow_copy sets the serializer on an object, return 2 to indicate to
+ * If shallow_copy sets the serializer on an object, return 2 to indicate to
* json_object_deep_copy that it should not attempt to use the standard userdata
* copy function.
*
* @return On success 1 or 2, -1 on errors
*/
-typedef int (json_c_shallow_copy_fn)(json_object *src, json_object *parent, const char *key, size_t index, json_object **dst);
+typedef int(json_c_shallow_copy_fn)(json_object *src, json_object *parent, const char *key,
+ size_t index, json_object **dst);
/**
* The default shallow copy implementation for use with json_object_deep_copy().
- * This simply calls the appropriate json_object_new_() function and
+ * This simply calls the appropriate json_object_new_() function and
* copies over the serializer function (_to_json_string internal field of
* the json_object structure) but not any _userdata or _user_delete values.
*
@@ -1005,7 +1038,7 @@
*
* @return 1 on success, -1 on errors, but never 2.
*/
-json_c_shallow_copy_fn json_c_shallow_copy_default;
+JSON_EXPORT json_c_shallow_copy_fn json_c_shallow_copy_default;
/**
* Copy the contents of the JSON object.
@@ -1026,7 +1059,8 @@
* or if the destination pointer is non-NULL
*/
-JSON_EXPORT int json_object_deep_copy(struct json_object *src, struct json_object **dst, json_c_shallow_copy_fn *shallow_copy);
+JSON_EXPORT int json_object_deep_copy(struct json_object *src, struct json_object **dst,
+ json_c_shallow_copy_fn *shallow_copy);
#ifdef __cplusplus
}
#endif
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_object_iterator.c thunderbird-91.8.1+build1/comm/third_party/json-c/json_object_iterator.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_object_iterator.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_object_iterator.c 2022-04-15 07:49:21.000000000 +0000
@@ -9,6 +9,7 @@
*
*******************************************************************************
*/
+#include "config.h"
#include
@@ -53,111 +54,100 @@
/// Our current representation of the "end" iterator;
///
/// @note May not always be NULL
-static const void* kObjectEndIterValue = NULL;
+static const void *kObjectEndIterValue = NULL;
/**
* ****************************************************************************
*/
-struct json_object_iterator
-json_object_iter_begin(struct json_object* obj)
+struct json_object_iterator json_object_iter_begin(struct json_object *obj)
{
- struct json_object_iterator iter;
- struct lh_table* pTable;
+ struct json_object_iterator iter;
+ struct lh_table *pTable;
- /// @note json_object_get_object will return NULL if passed NULL
- /// or a non-json_type_object instance
- pTable = json_object_get_object(obj);
- JASSERT(NULL != pTable);
+ /// @note json_object_get_object will return NULL if passed NULL
+ /// or a non-json_type_object instance
+ pTable = json_object_get_object(obj);
+ JASSERT(NULL != pTable);
- /// @note For a pair-less Object, head is NULL, which matches our
- /// definition of the "end" iterator
- iter.opaque_ = pTable->head;
- return iter;
+ /// @note For a pair-less Object, head is NULL, which matches our
+ /// definition of the "end" iterator
+ iter.opaque_ = pTable->head;
+ return iter;
}
/**
* ****************************************************************************
*/
-struct json_object_iterator
-json_object_iter_end(const struct json_object* obj)
+struct json_object_iterator json_object_iter_end(const struct json_object *obj)
{
- struct json_object_iterator iter;
+ struct json_object_iterator iter;
- JASSERT(NULL != obj);
- JASSERT(json_object_is_type(obj, json_type_object));
+ JASSERT(NULL != obj);
+ JASSERT(json_object_is_type(obj, json_type_object));
- iter.opaque_ = kObjectEndIterValue;
+ iter.opaque_ = kObjectEndIterValue;
- return iter;
+ return iter;
}
/**
* ****************************************************************************
*/
-void
-json_object_iter_next(struct json_object_iterator* iter)
+void json_object_iter_next(struct json_object_iterator *iter)
{
- JASSERT(NULL != iter);
- JASSERT(kObjectEndIterValue != iter->opaque_);
+ JASSERT(NULL != iter);
+ JASSERT(kObjectEndIterValue != iter->opaque_);
- iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next;
+ iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next;
}
-
/**
* ****************************************************************************
*/
-const char*
-json_object_iter_peek_name(const struct json_object_iterator* iter)
+const char *json_object_iter_peek_name(const struct json_object_iterator *iter)
{
- JASSERT(NULL != iter);
- JASSERT(kObjectEndIterValue != iter->opaque_);
+ JASSERT(NULL != iter);
+ JASSERT(kObjectEndIterValue != iter->opaque_);
- return (const char*)(((const struct lh_entry *)iter->opaque_)->k);
+ return (const char *)(((const struct lh_entry *)iter->opaque_)->k);
}
-
/**
* ****************************************************************************
*/
-struct json_object*
-json_object_iter_peek_value(const struct json_object_iterator* iter)
+struct json_object *json_object_iter_peek_value(const struct json_object_iterator *iter)
{
- JASSERT(NULL != iter);
- JASSERT(kObjectEndIterValue != iter->opaque_);
+ JASSERT(NULL != iter);
+ JASSERT(kObjectEndIterValue != iter->opaque_);
- return (struct json_object*)lh_entry_v((const struct lh_entry *)iter->opaque_);
+ return (struct json_object *)lh_entry_v((const struct lh_entry *)iter->opaque_);
}
-
/**
* ****************************************************************************
*/
-json_bool
-json_object_iter_equal(const struct json_object_iterator* iter1,
- const struct json_object_iterator* iter2)
+json_bool json_object_iter_equal(const struct json_object_iterator *iter1,
+ const struct json_object_iterator *iter2)
{
- JASSERT(NULL != iter1);
- JASSERT(NULL != iter2);
+ JASSERT(NULL != iter1);
+ JASSERT(NULL != iter2);
- return (iter1->opaque_ == iter2->opaque_);
+ return (iter1->opaque_ == iter2->opaque_);
}
-
/**
* ****************************************************************************
*/
-struct json_object_iterator
-json_object_iter_init_default(void)
+struct json_object_iterator json_object_iter_init_default(void)
{
- struct json_object_iterator iter;
+ struct json_object_iterator iter;
- /**
- * @note Make this a negative, invalid value, such that
- * accidental access to it would likely be trapped by the
- * hardware as an invalid address.
- */
- iter.opaque_ = NULL;
+ /**
+ * @note Make this a negative, invalid value, such that
+ * accidental access to it would likely be trapped by the
+ * hardware as an invalid address.
+ */
+ iter.opaque_ = NULL;
- return iter;
+ return iter;
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_object_iterator.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_object_iterator.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_object_iterator.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_object_iterator.h 2022-04-15 07:49:21.000000000 +0000
@@ -20,10 +20,10 @@
*******************************************************************************
*/
-
#ifndef JSON_OBJECT_ITERATOR_H
#define JSON_OBJECT_ITERATOR_H
+#include "json_types.h"
#include
#ifdef __cplusplus
@@ -39,17 +39,16 @@
* The opaque iterator that references a name/value pair within
* a JSON Object instance or the "end" iterator value.
*/
-struct json_object_iterator {
- const void* opaque_;
+struct json_object_iterator
+{
+ const void *opaque_;
};
-
/**
* forward declaration of json-c's JSON value instance structure
*/
struct json_object;
-
/**
* Initializes an iterator structure to a "default" value that
* is convenient for initializing an iterator variable to a
@@ -72,8 +71,7 @@
*
* @return json_object_iterator
*/
-struct json_object_iterator
-json_object_iter_init_default(void);
+JSON_EXPORT struct json_object_iterator json_object_iter_init_default(void);
/** Retrieves an iterator to the first pair of the JSON Object.
*
@@ -106,8 +104,7 @@
*
* @endcode
*/
-struct json_object_iterator
-json_object_iter_begin(struct json_object* obj);
+JSON_EXPORT struct json_object_iterator json_object_iter_begin(struct json_object *obj);
/** Retrieves the iterator that represents the position beyond the
* last pair of the given JSON Object instance.
@@ -137,8 +134,7 @@
* (i.e., NOT the last pair, but "beyond the last
* pair" value)
*/
-struct json_object_iterator
-json_object_iter_end(const struct json_object* obj);
+JSON_EXPORT struct json_object_iterator json_object_iter_end(const struct json_object *obj);
/** Returns an iterator to the next pair, if any
*
@@ -155,9 +151,7 @@
* of json_object_iter_end() for the same JSON Object
* instance.
*/
-void
-json_object_iter_next(struct json_object_iterator* iter);
-
+JSON_EXPORT void json_object_iter_next(struct json_object_iterator *iter);
/** Returns a const pointer to the name of the pair referenced
* by the given iterator.
@@ -174,9 +168,7 @@
* deleted or modified, and MUST NOT be modified or
* freed by the user.
*/
-const char*
-json_object_iter_peek_name(const struct json_object_iterator* iter);
-
+JSON_EXPORT const char *json_object_iter_peek_name(const struct json_object_iterator *iter);
/** Returns a pointer to the json-c instance representing the
* value of the referenced name/value pair, without altering
@@ -197,9 +189,8 @@
* the JSON Null value as a NULL json_object instance
* pointer.
*/
-struct json_object*
-json_object_iter_peek_value(const struct json_object_iterator* iter);
-
+JSON_EXPORT struct json_object *
+json_object_iter_peek_value(const struct json_object_iterator *iter);
/** Tests two iterators for equality. Typically used to test
* for end of iteration by comparing an iterator to the
@@ -227,14 +218,11 @@
* reference the same name/value pair or are both at
* "end"); zero if they are not equal.
*/
-json_bool
-json_object_iter_equal(const struct json_object_iterator* iter1,
- const struct json_object_iterator* iter2);
-
+JSON_EXPORT json_bool json_object_iter_equal(const struct json_object_iterator *iter1,
+ const struct json_object_iterator *iter2);
#ifdef __cplusplus
}
#endif
-
#endif /* JSON_OBJECT_ITERATOR_H */
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_object_private.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_object_private.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_object_private.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_object_private.h 2022-04-15 07:49:21.000000000 +0000
@@ -20,41 +20,84 @@
extern "C" {
#endif
-#define LEN_DIRECT_STRING_DATA 32 /**< how many bytes are directly stored in json_object for strings? */
+struct json_object;
+#include "json_inttypes.h"
+#include "json_types.h"
+
+#ifdef HAVE_UNISTD_H
+#include
+#endif /* HAVE_UNISTD_H */
+
+#ifdef _MSC_VER
+#include
+typedef SSIZE_T ssize_t;
+#endif
-typedef void (json_object_private_delete_fn)(struct json_object *o);
+/* json object int type, support extension*/
+typedef enum json_object_int_type
+{
+ json_object_int_type_int64,
+ json_object_int_type_uint64
+} json_object_int_type;
struct json_object
{
- enum json_type o_type;
- json_object_private_delete_fn *_delete;
- json_object_to_json_string_fn *_to_json_string;
- int _ref_count;
- struct printbuf *_pb;
- union data {
- json_bool c_boolean;
- double c_double;
- int64_t c_int64;
- struct lh_table *c_object;
- struct array_list *c_array;
- struct {
- union {
- /* optimize: if we have small strings, we can store them
- * directly. This saves considerable CPU cycles AND memory.
- */
- char *ptr;
- char data[LEN_DIRECT_STRING_DATA];
- } str;
- int len;
- } c_string;
- } o;
- json_object_delete_fn *_user_delete;
- void *_userdata;
+ enum json_type o_type;
+ uint32_t _ref_count;
+ json_object_to_json_string_fn *_to_json_string;
+ struct printbuf *_pb;
+ json_object_delete_fn *_user_delete;
+ void *_userdata;
+ // Actually longer, always malloc'd as some more-specific type.
+ // The rest of a struct json_object_${o_type} follows
+};
+
+struct json_object_object
+{
+ struct json_object base;
+ struct lh_table *c_object;
+};
+struct json_object_array
+{
+ struct json_object base;
+ struct array_list *c_array;
+};
+
+struct json_object_boolean
+{
+ struct json_object base;
+ json_bool c_boolean;
+};
+struct json_object_double
+{
+ struct json_object base;
+ double c_double;
+};
+struct json_object_int
+{
+ struct json_object base;
+ enum json_object_int_type cint_type;
+ union
+ {
+ int64_t c_int64;
+ uint64_t c_uint64;
+ } cint;
+};
+struct json_object_string
+{
+ struct json_object base;
+ ssize_t len; // Signed b/c negative lengths indicate data is a pointer
+ // Consider adding an "alloc" field here, if json_object_set_string calls
+ // to expand the length of a string are common operations to perform.
+ union
+ {
+ char idata[1]; // Immediate data. Actually longer
+ char *pdata; // Only when len < 0
+ } c_string;
};
void _json_c_set_last_err(const char *err_fmt, ...);
-extern const char *json_number_chars;
extern const char *json_hex_chars;
#ifdef __cplusplus
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_pointer.c thunderbird-91.8.1+build1/comm/third_party/json-c/json_pointer.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_pointer.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_pointer.c 2022-04-15 07:49:21.000000000 +0000
@@ -10,11 +10,11 @@
#include "strerror_override.h"
+#include
#include
#include
#include
#include
-#include
#include "json_pointer.h"
#include "strdup_compat.h"
@@ -28,9 +28,10 @@
static void string_replace_all_occurrences_with_char(char *s, const char *occur, char repl_char)
{
int slen = strlen(s);
- int skip = strlen(occur) - 1; /* length of the occurence, minus the char we're replacing */
+ int skip = strlen(occur) - 1; /* length of the occurrence, minus the char we're replacing */
char *p = s;
- while ((p = strstr(p, occur))) {
+ while ((p = strstr(p, occur)))
+ {
*p = repl_char;
p++;
slen -= skip;
@@ -41,10 +42,13 @@
static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx)
{
int i, len = strlen(path);
- /* this code-path optimizes a bit, for when we reference the 0-9 index range in a JSON array
- and because leading zeros not allowed */
- if (len == 1) {
- if (isdigit((int)path[0])) {
+ /* this code-path optimizes a bit, for when we reference the 0-9 index range
+ * in a JSON array and because leading zeros not allowed
+ */
+ if (len == 1)
+ {
+ if (isdigit((unsigned char)path[0]))
+ {
*idx = (path[0] - '0');
goto check_oob;
}
@@ -52,26 +56,31 @@
return 0;
}
/* leading zeros not allowed per RFC */
- if (path[0] == '0') {
+ if (path[0] == '0')
+ {
errno = EINVAL;
return 0;
}
/* RFC states base-10 decimals */
- for (i = 0; i < len; i++) {
- if (!isdigit((int)path[i])) {
+ for (i = 0; i < len; i++)
+ {
+ if (!isdigit((unsigned char)path[i]))
+ {
errno = EINVAL;
return 0;
}
}
*idx = strtol(path, NULL, 10);
- if (*idx < 0) {
+ if (*idx < 0)
+ {
errno = EINVAL;
return 0;
}
check_oob:
len = json_object_array_length(jo);
- if (*idx >= len) {
+ if (*idx >= len)
+ {
errno = ENOENT;
return 0;
}
@@ -79,14 +88,17 @@
return 1;
}
-static int json_pointer_get_single_path(struct json_object *obj, char *path, struct json_object **value)
+static int json_pointer_get_single_path(struct json_object *obj, char *path,
+ struct json_object **value)
{
- if (json_object_is_type(obj, json_type_array)) {
+ if (json_object_is_type(obj, json_type_array))
+ {
int32_t idx;
if (!is_valid_index(obj, path, &idx))
return -1;
obj = json_object_array_get_idx(obj, idx);
- if (obj) {
+ if (obj)
+ {
if (value)
*value = obj;
return 0;
@@ -100,7 +112,8 @@
string_replace_all_occurrences_with_char(path, "~1", '/');
string_replace_all_occurrences_with_char(path, "~0", '~');
- if (!json_object_object_get_ex(obj, path, value)) {
+ if (!json_object_object_get_ex(obj, path, value))
+ {
errno = ENOENT;
return -1;
}
@@ -108,12 +121,11 @@
return 0;
}
-static int json_pointer_set_single_path(
- struct json_object *parent,
- const char *path,
- struct json_object *value)
+static int json_pointer_set_single_path(struct json_object *parent, const char *path,
+ struct json_object *value)
{
- if (json_object_is_type(parent, json_type_array)) {
+ if (json_object_is_type(parent, json_type_array))
+ {
int32_t idx;
/* RFC (Chapter 4) states that '-' may be used to add new elements to an array */
if (path[0] == '-' && path[1] == '\0')
@@ -124,26 +136,27 @@
}
/* path replacements should have been done in json_pointer_get_single_path(),
- and we should still be good here */
+ * and we should still be good here
+ */
if (json_object_is_type(parent, json_type_object))
return json_object_object_add(parent, path, value);
- /* Getting here means that we tried to "dereference" a primitive JSON type (like string, int, bool).
- i.e. add a sub-object to it */
+ /* Getting here means that we tried to "dereference" a primitive JSON type
+ * (like string, int, bool).i.e. add a sub-object to it
+ */
errno = ENOENT;
return -1;
}
-static int json_pointer_get_recursive(
- struct json_object *obj,
- char *path,
- struct json_object **value)
+static int json_pointer_get_recursive(struct json_object *obj, char *path,
+ struct json_object **value)
{
char *endp;
int rc;
/* All paths (on each recursion level must have a leading '/' */
- if (path[0] != '/') {
+ if (path[0] != '/')
+ {
errno = EINVAL;
return -1;
}
@@ -157,8 +170,10 @@
if ((rc = json_pointer_get_single_path(obj, path, &obj)))
return rc;
- if (endp) {
- *endp = '/'; /* Put the slash back, so that the sanity check passes on next recursion level */
+ if (endp)
+ {
+ /* Put the slash back, so that the sanity check passes on next recursion level */
+ *endp = '/';
return json_pointer_get_recursive(obj, endp, value);
}
@@ -174,19 +189,22 @@
char *path_copy = NULL;
int rc;
- if (!obj || !path) {
+ if (!obj || !path)
+ {
errno = EINVAL;
return -1;
}
- if (path[0] == '\0') {
+ if (path[0] == '\0')
+ {
if (res)
*res = obj;
return 0;
}
/* pass a working copy to the recursive call */
- if (!(path_copy = strdup(path))) {
+ if (!(path_copy = strdup(path)))
+ {
errno = ENOMEM;
return -1;
}
@@ -202,7 +220,8 @@
int rc = 0;
va_list args;
- if (!obj || !path_fmt) {
+ if (!obj || !path_fmt)
+ {
errno = EINVAL;
return -1;
}
@@ -214,7 +233,8 @@
if (rc < 0)
return rc;
- if (path_copy[0] == '\0') {
+ if (path_copy[0] == '\0')
+ {
if (res)
*res = obj;
goto out;
@@ -234,30 +254,35 @@
struct json_object *set = NULL;
int rc;
- if (!obj || !path) {
+ if (!obj || !path)
+ {
errno = EINVAL;
return -1;
}
- if (path[0] == '\0') {
+ if (path[0] == '\0')
+ {
json_object_put(*obj);
*obj = value;
return 0;
}
- if (path[0] != '/') {
+ if (path[0] != '/')
+ {
errno = EINVAL;
return -1;
}
/* If there's only 1 level to set, stop here */
- if ((endp = strrchr(path, '/')) == path) {
+ if ((endp = strrchr(path, '/')) == path)
+ {
path++;
return json_pointer_set_single_path(*obj, path, value);
}
/* pass a working copy to the recursive call */
- if (!(path_copy = strdup(path))) {
+ if (!(path_copy = strdup(path)))
+ {
errno = ENOMEM;
return -1;
}
@@ -272,7 +297,8 @@
return json_pointer_set_single_path(set, endp, value);
}
-int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...)
+int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt,
+ ...)
{
char *endp;
char *path_copy = NULL;
@@ -280,7 +306,8 @@
va_list args;
int rc = 0;
- if (!obj || !path_fmt) {
+ if (!obj || !path_fmt)
+ {
errno = EINVAL;
return -1;
}
@@ -293,20 +320,23 @@
if (rc < 0)
return rc;
- if (path_copy[0] == '\0') {
+ if (path_copy[0] == '\0')
+ {
json_object_put(*obj);
*obj = value;
goto out;
}
- if (path_copy[0] != '/') {
+ if (path_copy[0] != '/')
+ {
errno = EINVAL;
rc = -1;
goto out;
}
/* If there's only 1 level to set, stop here */
- if ((endp = strrchr(path_copy, '/')) == path_copy) {
+ if ((endp = strrchr(path_copy, '/')) == path_copy)
+ {
set = *obj;
goto set_single_path;
}
@@ -324,4 +354,3 @@
free(path_copy);
return rc;
}
-
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_pointer.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_pointer.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_pointer.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_pointer.h 2022-04-15 07:49:21.000000000 +0000
@@ -39,12 +39,13 @@
*
* @param obj the json_object instance/tree from where to retrieve sub-objects
* @param path a (RFC6901) string notation for the sub-object to retrieve
- * @param res a pointer where to store a reference to the json_object
+ * @param res a pointer that stores a reference to the json_object
* associated with the given path
*
* @return negative if an error (or not found), or 0 if succeeded
*/
-int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res);
+JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path,
+ struct json_object **res);
/**
* This is a variant of 'json_pointer_get()' that supports printf() style arguments.
@@ -56,13 +57,14 @@
* aspects when using this function.
*
* @param obj the json_object instance/tree to which to add a sub-object
- * @param res a pointer where to store a reference to the json_object
+ * @param res a pointer that stores a reference to the json_object
* associated with the given path
* @param path_fmt a printf() style format for the path
*
* @return negative if an error (or not found), or 0 if succeeded
*/
-int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...);
+JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object **res,
+ const char *path_fmt, ...);
/**
* Sets JSON object 'value' in the 'obj' tree at the location specified
@@ -93,7 +95,8 @@
*
* @return negative if an error (or not found), or 0 if succeeded
*/
-int json_pointer_set(struct json_object **obj, const char *path, struct json_object *value);
+JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path,
+ struct json_object *value);
/**
* This is a variant of 'json_pointer_set()' that supports printf() style arguments.
@@ -110,8 +113,8 @@
*
* @return negative if an error (or not found), or 0 if succeeded
*/
-int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...);
-
+JSON_EXPORT int json_pointer_setf(struct json_object **obj, struct json_object *value,
+ const char *path_fmt, ...);
#ifdef __cplusplus
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_tokener.c thunderbird-91.8.1+build1/comm/third_party/json-c/json_tokener.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_tokener.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_tokener.c 2022-04-15 07:49:21.000000000 +0000
@@ -15,23 +15,23 @@
#include "config.h"
-#include
#include "math_compat.h"
+#include
+#include
+#include
+#include
+#include
#include
#include
-#include
-#include
#include
-#include
#include "debug.h"
-#include "printbuf.h"
-#include "arraylist.h"
#include "json_inttypes.h"
#include "json_object.h"
#include "json_object_private.h"
#include "json_tokener.h"
#include "json_util.h"
+#include "printbuf.h"
#include "strdup_compat.h"
#ifdef HAVE_LOCALE_H
@@ -40,14 +40,17 @@
#ifdef HAVE_XLOCALE_H
#include
#endif
+#ifdef HAVE_STRINGS_H
+#include
+#endif /* HAVE_STRINGS_H */
-#define jt_hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
+#define jt_hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x)&7) + 9)
#if !HAVE_STRNCASECMP && defined(_MSC_VER)
- /* MSC has the version as _strnicmp */
-# define strncasecmp _strnicmp
+/* MSC has the version as _strnicmp */
+#define strncasecmp _strnicmp
#elif !HAVE_STRNCASECMP
-# error You do not have strncasecmp on your system.
+#error You do not have strncasecmp on your system.
#endif /* HAVE_STRNCASECMP */
/* Use C99 NAN by default; if not available, nan("") should work too. */
@@ -67,27 +70,38 @@
static const char json_false_str[] = "false";
static const int json_false_str_len = sizeof(json_false_str) - 1;
-static const char* json_tokener_errors[] = {
- "success",
- "continue",
- "nesting too deep",
- "unexpected end of data",
- "unexpected character",
- "null expected",
- "boolean expected",
- "number expected",
- "array value separator ',' expected",
- "quoted object property name expected",
- "object property name separator ':' expected",
- "object value separator ',' expected",
- "invalid string sequence",
- "expected comment",
- "buffer size overflow"
+/* clang-format off */
+static const char *json_tokener_errors[] = {
+ "success",
+ "continue",
+ "nesting too deep",
+ "unexpected end of data",
+ "unexpected character",
+ "null expected",
+ "boolean expected",
+ "number expected",
+ "array value separator ',' expected",
+ "quoted object property name expected",
+ "object property name separator ':' expected",
+ "object value separator ',' expected",
+ "invalid string sequence",
+ "expected comment",
+ "invalid utf-8 string",
+ "buffer size overflow"
};
+/* clang-format on */
+
+/**
+ * validete the utf-8 string in strict model.
+ * if not utf-8 format, return err.
+ */
+static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes);
+
+static int json_tokener_parse_double(const char *buf, int len, double *retval);
const char *json_tokener_error_desc(enum json_tokener_error jerr)
{
- int jerr_int = (int) jerr;
+ int jerr_int = (int)jerr;
if (jerr_int < 0 ||
jerr_int >= (int)(sizeof(json_tokener_errors) / sizeof(json_tokener_errors[0])))
return "Unknown error, "
@@ -101,95 +115,107 @@
}
/* Stuff for decoding unicode sequences */
-#define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
-#define IS_LOW_SURROGATE(uc) (((uc) & 0xFC00) == 0xDC00)
-#define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
-static unsigned char utf8_replacement_char[3] = { 0xEF, 0xBF, 0xBD };
-
-struct json_tokener* json_tokener_new_ex(int depth)
-{
- struct json_tokener *tok;
-
- tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
- if (!tok) return NULL;
- tok->stack = (struct json_tokener_srec *) calloc(depth,
- sizeof(struct json_tokener_srec));
- if (!tok->stack) {
- free(tok);
- return NULL;
- }
- tok->pb = printbuf_new();
- tok->max_depth = depth;
- json_tokener_reset(tok);
- return tok;
+#define IS_HIGH_SURROGATE(uc) (((uc)&0xFC00) == 0xD800)
+#define IS_LOW_SURROGATE(uc) (((uc)&0xFC00) == 0xDC00)
+#define DECODE_SURROGATE_PAIR(hi, lo) ((((hi)&0x3FF) << 10) + ((lo)&0x3FF) + 0x10000)
+static unsigned char utf8_replacement_char[3] = {0xEF, 0xBF, 0xBD};
+
+struct json_tokener *json_tokener_new_ex(int depth)
+{
+ struct json_tokener *tok;
+
+ tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
+ if (!tok)
+ return NULL;
+ tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
+ if (!tok->stack)
+ {
+ free(tok);
+ return NULL;
+ }
+ tok->pb = printbuf_new();
+ tok->max_depth = depth;
+ json_tokener_reset(tok);
+ return tok;
}
-struct json_tokener* json_tokener_new(void)
+struct json_tokener *json_tokener_new(void)
{
- return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
+ return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
}
void json_tokener_free(struct json_tokener *tok)
{
- json_tokener_reset(tok);
- if (tok->pb) printbuf_free(tok->pb);
- free(tok->stack);
- free(tok);
+ json_tokener_reset(tok);
+ if (tok->pb)
+ printbuf_free(tok->pb);
+ free(tok->stack);
+ free(tok);
}
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
{
- tok->stack[depth].state = json_tokener_state_eatws;
- tok->stack[depth].saved_state = json_tokener_state_start;
- json_object_put(tok->stack[depth].current);
- tok->stack[depth].current = NULL;
- free(tok->stack[depth].obj_field_name);
- tok->stack[depth].obj_field_name = NULL;
+ tok->stack[depth].state = json_tokener_state_eatws;
+ tok->stack[depth].saved_state = json_tokener_state_start;
+ json_object_put(tok->stack[depth].current);
+ tok->stack[depth].current = NULL;
+ free(tok->stack[depth].obj_field_name);
+ tok->stack[depth].obj_field_name = NULL;
}
void json_tokener_reset(struct json_tokener *tok)
{
- int i;
- if (!tok)
- return;
-
- for(i = tok->depth; i >= 0; i--)
- json_tokener_reset_level(tok, i);
- tok->depth = 0;
- tok->err = json_tokener_success;
+ int i;
+ if (!tok)
+ return;
+
+ for (i = tok->depth; i >= 0; i--)
+ json_tokener_reset_level(tok, i);
+ tok->depth = 0;
+ tok->err = json_tokener_success;
}
-struct json_object* json_tokener_parse(const char *str)
+struct json_object *json_tokener_parse(const char *str)
{
- enum json_tokener_error jerr_ignored;
- struct json_object* obj;
- obj = json_tokener_parse_verbose(str, &jerr_ignored);
- return obj;
+ enum json_tokener_error jerr_ignored;
+ struct json_object *obj;
+ obj = json_tokener_parse_verbose(str, &jerr_ignored);
+ return obj;
}
-struct json_object* json_tokener_parse_verbose(const char *str,
- enum json_tokener_error *error)
+struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
{
- struct json_tokener* tok;
- struct json_object* obj;
+ struct json_tokener *tok;
+ struct json_object *obj;
- tok = json_tokener_new();
- if (!tok)
- return NULL;
- obj = json_tokener_parse_ex(tok, str, -1);
- *error = tok->err;
- if(tok->err != json_tokener_success) {
+ tok = json_tokener_new();
+ if (!tok)
+ return NULL;
+ obj = json_tokener_parse_ex(tok, str, -1);
+ *error = tok->err;
+ if (tok->err != json_tokener_success
+#if 0
+ /* This would be a more sensible default, and cause parsing
+ * things like "null123" to fail when the caller can't know
+ * where the parsing left off, but starting to fail would
+ * be a notable behaviour change. Save for a 1.0 release.
+ */
+ || json_tokener_get_parse_end(tok) != strlen(str)
+#endif
+ )
+
+ {
if (obj != NULL)
json_object_put(obj);
- obj = NULL;
- }
+ obj = NULL;
+ }
- json_tokener_free(tok);
- return obj;
+ json_tokener_free(tok);
+ return obj;
}
-#define state tok->stack[tok->depth].state
-#define saved_state tok->stack[tok->depth].saved_state
+#define state tok->stack[tok->depth].state
+#define saved_state tok->stack[tok->depth].saved_state
#define current tok->stack[tok->depth].current
#define obj_field_name tok->stack[tok->depth].obj_field_name
@@ -209,789 +235,1034 @@
/* PEEK_CHAR(dest, tok) macro:
* Peeks at the current char and stores it in dest.
* Returns 1 on success, sets tok->err and returns 0 if no more chars.
- * Implicit inputs: str, len vars
+ * Implicit inputs: str, len, nBytesp vars
*/
-#define PEEK_CHAR(dest, tok) \
- (((tok)->char_offset == len) ? \
- (((tok)->depth == 0 && \
- state == json_tokener_state_eatws && \
- saved_state == json_tokener_state_finish \
- ) ? \
- (((tok)->err = json_tokener_success), 0) \
- : \
- (((tok)->err = json_tokener_continue), 0) \
- ) : \
- (((dest) = *str), 1) \
- )
+#define PEEK_CHAR(dest, tok) \
+ (((tok)->char_offset == len) \
+ ? (((tok)->depth == 0 && state == json_tokener_state_eatws && \
+ saved_state == json_tokener_state_finish) \
+ ? (((tok)->err = json_tokener_success), 0) \
+ : (((tok)->err = json_tokener_continue), 0)) \
+ : (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && \
+ (!json_tokener_validate_utf8(*str, nBytesp))) \
+ ? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
+ : (((dest) = *str), 1)))
/* ADVANCE_CHAR() macro:
- * Incrementes str & tok->char_offset.
+ * Increments str & tok->char_offset.
* For convenience of existing conditionals, returns the old value of c (0 on eof)
* Implicit inputs: c var
*/
-#define ADVANCE_CHAR(str, tok) \
- ( ++(str), ((tok)->char_offset)++, c)
-
+#define ADVANCE_CHAR(str, tok) (++(str), ((tok)->char_offset)++, c)
/* End optimization macro defs */
-
-struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
- const char *str, int len)
+struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str, int len)
{
- struct json_object *obj = NULL;
- char c = '\1';
+ struct json_object *obj = NULL;
+ char c = '\1';
+ unsigned int nBytes = 0;
+ unsigned int *nBytesp = &nBytes;
+
#ifdef HAVE_USELOCALE
- locale_t oldlocale = uselocale(NULL);
- locale_t newloc;
+ locale_t oldlocale = uselocale(NULL);
+ locale_t newloc;
#elif defined(HAVE_SETLOCALE)
- char *oldlocale = NULL;
+ char *oldlocale = NULL;
#endif
- tok->char_offset = 0;
- tok->err = json_tokener_success;
+ tok->char_offset = 0;
+ tok->err = json_tokener_success;
- /* this interface is presently not 64-bit clean due to the int len argument
- and the internal printbuf interface that takes 32-bit int len arguments
- so the function limits the maximum string size to INT32_MAX (2GB).
- If the function is called with len == -1 then strlen is called to check
- the string length is less than INT32_MAX (2GB) */
- if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX)) {
- tok->err = json_tokener_error_size;
- return NULL;
- }
+ /* this interface is presently not 64-bit clean due to the int len argument
+ * and the internal printbuf interface that takes 32-bit int len arguments
+ * so the function limits the maximum string size to INT32_MAX (2GB).
+ * If the function is called with len == -1 then strlen is called to check
+ * the string length is less than INT32_MAX (2GB)
+ */
+ if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX))
+ {
+ tok->err = json_tokener_error_size;
+ return NULL;
+ }
#ifdef HAVE_USELOCALE
- {
- locale_t duploc = duplocale(oldlocale);
- newloc = newlocale(LC_NUMERIC, "C", duploc);
- // XXX at least Debian 8.4 has a bug in newlocale where it doesn't
- // change the decimal separator unless you set LC_TIME!
- if (newloc)
- {
- duploc = newloc; // original duploc has been freed by newlocale()
- newloc = newlocale(LC_TIME, "C", duploc);
- }
- if (newloc == NULL)
- {
- freelocale(duploc);
- return NULL;
- }
- uselocale(newloc);
- }
+ {
+ locale_t duploc = duplocale(oldlocale);
+ newloc = newlocale(LC_NUMERIC_MASK, "C", duploc);
+ if (newloc == NULL)
+ {
+ freelocale(duploc);
+ return NULL;
+ }
+ uselocale(newloc);
+ }
#elif defined(HAVE_SETLOCALE)
- {
- char *tmplocale;
- tmplocale = setlocale(LC_NUMERIC, NULL);
- if (tmplocale) oldlocale = strdup(tmplocale);
- setlocale(LC_NUMERIC, "C");
- }
+ {
+ char *tmplocale;
+ tmplocale = setlocale(LC_NUMERIC, NULL);
+ if (tmplocale)
+ oldlocale = strdup(tmplocale);
+ setlocale(LC_NUMERIC, "C");
+ }
#endif
- while (PEEK_CHAR(c, tok)) {
+ while (PEEK_CHAR(c, tok)) // Note: c might be '\0' !
+ {
- redo_char:
- switch(state) {
+ redo_char:
+ switch (state)
+ {
- case json_tokener_state_eatws:
- /* Advance until we change state */
- while (isspace((int)c)) {
- if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
- goto out;
- }
- if(c == '/' && !(tok->flags & JSON_TOKENER_STRICT)) {
- printbuf_reset(tok->pb);
- printbuf_memappend_fast(tok->pb, &c, 1);
- state = json_tokener_state_comment_start;
- } else {
- state = saved_state;
- goto redo_char;
- }
- break;
-
- case json_tokener_state_start:
- switch(c) {
- case '{':
- state = json_tokener_state_eatws;
- saved_state = json_tokener_state_object_field_start;
- current = json_object_new_object();
- if(current == NULL)
- goto out;
- break;
- case '[':
- state = json_tokener_state_eatws;
- saved_state = json_tokener_state_array;
- current = json_object_new_array();
- if(current == NULL)
- goto out;
- break;
- case 'I':
- case 'i':
- state = json_tokener_state_inf;
- printbuf_reset(tok->pb);
- tok->st_pos = 0;
- goto redo_char;
- case 'N':
- case 'n':
- state = json_tokener_state_null; // or NaN
- printbuf_reset(tok->pb);
- tok->st_pos = 0;
- goto redo_char;
- case '\'':
- if (tok->flags & JSON_TOKENER_STRICT) {
- /* in STRICT mode only double-quote are allowed */
- tok->err = json_tokener_error_parse_unexpected;
- goto out;
- }
- /* FALLTHRU */
- case '"':
- state = json_tokener_state_string;
- printbuf_reset(tok->pb);
- tok->quote_char = c;
- break;
- case 'T':
- case 't':
- case 'F':
- case 'f':
- state = json_tokener_state_boolean;
- printbuf_reset(tok->pb);
- tok->st_pos = 0;
- goto redo_char;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '-':
- state = json_tokener_state_number;
- printbuf_reset(tok->pb);
- tok->is_double = 0;
- goto redo_char;
- default:
- tok->err = json_tokener_error_parse_unexpected;
- goto out;
- }
- break;
-
- case json_tokener_state_finish:
- if(tok->depth == 0) goto out;
- obj = json_object_get(current);
- json_tokener_reset_level(tok, tok->depth);
- tok->depth--;
- goto redo_char;
-
- case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
- {
- /* If we were guaranteed to have len set, then we could (usually) handle
- * the entire "Infinity" check in a single strncmp (strncasecmp), but
- * since len might be -1 (i.e. "read until \0"), we need to check it
- * a character at a time.
- * Trying to handle it both ways would make this code considerably more
- * complicated with likely little performance benefit.
- */
- int is_negative = 0;
- const char *_json_inf_str = json_inf_str;
- if (!(tok->flags & JSON_TOKENER_STRICT))
- _json_inf_str = json_inf_str_lower;
-
- /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
- while (tok->st_pos < (int)json_inf_str_len)
- {
- char inf_char = *str;
- if (!(tok->flags & JSON_TOKENER_STRICT))
- inf_char = tolower((int)*str);
- if (inf_char != _json_inf_str[tok->st_pos])
+ case json_tokener_state_eatws:
+ /* Advance until we change state */
+ while (isspace((unsigned char)c))
+ {
+ if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
+ goto out;
+ }
+ if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
+ {
+ printbuf_reset(tok->pb);
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ state = json_tokener_state_comment_start;
+ }
+ else
+ {
+ state = saved_state;
+ goto redo_char;
+ }
+ break;
+
+ case json_tokener_state_start:
+ switch (c)
+ {
+ case '{':
+ state = json_tokener_state_eatws;
+ saved_state = json_tokener_state_object_field_start;
+ current = json_object_new_object();
+ if (current == NULL)
+ goto out;
+ break;
+ case '[':
+ state = json_tokener_state_eatws;
+ saved_state = json_tokener_state_array;
+ current = json_object_new_array();
+ if (current == NULL)
+ goto out;
+ break;
+ case 'I':
+ case 'i':
+ state = json_tokener_state_inf;
+ printbuf_reset(tok->pb);
+ tok->st_pos = 0;
+ goto redo_char;
+ case 'N':
+ case 'n':
+ state = json_tokener_state_null; // or NaN
+ printbuf_reset(tok->pb);
+ tok->st_pos = 0;
+ goto redo_char;
+ case '\'':
+ if (tok->flags & JSON_TOKENER_STRICT)
+ {
+ /* in STRICT mode only double-quote are allowed */
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ /* FALLTHRU */
+ case '"':
+ state = json_tokener_state_string;
+ printbuf_reset(tok->pb);
+ tok->quote_char = c;
+ break;
+ case 'T':
+ case 't':
+ case 'F':
+ case 'f':
+ state = json_tokener_state_boolean;
+ printbuf_reset(tok->pb);
+ tok->st_pos = 0;
+ goto redo_char;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ state = json_tokener_state_number;
+ printbuf_reset(tok->pb);
+ tok->is_double = 0;
+ goto redo_char;
+ default: tok->err = json_tokener_error_parse_unexpected; goto out;
+ }
+ break;
+
+ case json_tokener_state_finish:
+ if (tok->depth == 0)
+ goto out;
+ obj = json_object_get(current);
+ json_tokener_reset_level(tok, tok->depth);
+ tok->depth--;
+ goto redo_char;
+
+ case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
{
- tok->err = json_tokener_error_parse_unexpected;
- goto out;
+ /* If we were guaranteed to have len set, then we could (usually) handle
+ * the entire "Infinity" check in a single strncmp (strncasecmp), but
+ * since len might be -1 (i.e. "read until \0"), we need to check it
+ * a character at a time.
+ * Trying to handle it both ways would make this code considerably more
+ * complicated with likely little performance benefit.
+ */
+ int is_negative = 0;
+ const char *_json_inf_str = json_inf_str;
+ if (!(tok->flags & JSON_TOKENER_STRICT))
+ _json_inf_str = json_inf_str_lower;
+
+ /* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
+ while (tok->st_pos < (int)json_inf_str_len)
+ {
+ char inf_char = *str;
+ if (!(tok->flags & JSON_TOKENER_STRICT))
+ inf_char = tolower((unsigned char)*str);
+ if (inf_char != _json_inf_str[tok->st_pos])
+ {
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ tok->st_pos++;
+ (void)ADVANCE_CHAR(str, tok);
+ if (!PEEK_CHAR(c, tok))
+ {
+ /* out of input chars, for now at least */
+ goto out;
+ }
+ }
+ /* We checked the full length of "Infinity", so create the object.
+ * When handling -Infinity, the number parsing code will have dropped
+ * the "-" into tok->pb for us, so check it now.
+ */
+ if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
+ {
+ is_negative = 1;
+ }
+ current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
+ if (current == NULL)
+ goto out;
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
}
- tok->st_pos++;
- (void)ADVANCE_CHAR(str, tok);
- if (!PEEK_CHAR(c, tok))
+ break;
+ case json_tokener_state_null: /* aka starts with 'n' */
{
- /* out of input chars, for now at least */
- goto out;
+ int size;
+ int size_nan;
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ size = json_min(tok->st_pos + 1, json_null_str_len);
+ size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
+ if ((!(tok->flags & JSON_TOKENER_STRICT) &&
+ strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
+ (strncmp(json_null_str, tok->pb->buf, size) == 0))
+ {
+ if (tok->st_pos == json_null_str_len)
+ {
+ current = NULL;
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ }
+ else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
+ strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
+ (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
+ {
+ if (tok->st_pos == json_nan_str_len)
+ {
+ current = json_object_new_double(NAN);
+ if (current == NULL)
+ goto out;
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ }
+ else
+ {
+ tok->err = json_tokener_error_parse_null;
+ goto out;
+ }
+ tok->st_pos++;
}
- }
- /* We checked the full length of "Infinity", so create the object.
- * When handling -Infinity, the number parsing code will have dropped
- * the "-" into tok->pb for us, so check it now.
- */
- if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
- {
- is_negative = 1;
- }
- current = json_object_new_double(is_negative
- ? -INFINITY : INFINITY);
- if (current == NULL)
- goto out;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- goto redo_char;
-
- }
- break;
- case json_tokener_state_null: /* aka starts with 'n' */
- {
- int size;
- int size_nan;
- printbuf_memappend_fast(tok->pb, &c, 1);
- size = json_min(tok->st_pos+1, json_null_str_len);
- size_nan = json_min(tok->st_pos+1, json_nan_str_len);
- if((!(tok->flags & JSON_TOKENER_STRICT) &&
- strncasecmp(json_null_str, tok->pb->buf, size) == 0)
- || (strncmp(json_null_str, tok->pb->buf, size) == 0)
- ) {
- if (tok->st_pos == json_null_str_len) {
- current = NULL;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- goto redo_char;
- }
- }
- else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
- strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
- (strncmp(json_nan_str, tok->pb->buf, size_nan) == 0)
- )
- {
- if (tok->st_pos == json_nan_str_len)
+ break;
+
+ case json_tokener_state_comment_start:
+ if (c == '*')
+ {
+ state = json_tokener_state_comment;
+ }
+ else if (c == '/')
+ {
+ state = json_tokener_state_comment_eol;
+ }
+ else
+ {
+ tok->err = json_tokener_error_parse_comment;
+ goto out;
+ }
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ break;
+
+ case json_tokener_state_comment:
{
- current = json_object_new_double(NAN);
- if (current == NULL)
- goto out;
- saved_state = json_tokener_state_finish;
+ /* Advance until we change state */
+ const char *case_start = str;
+ while (c != '*')
+ {
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
+ {
+ printbuf_memappend_fast(tok->pb, case_start,
+ str - case_start);
+ goto out;
+ }
+ }
+ printbuf_memappend_fast(tok->pb, case_start, 1 + str - case_start);
+ state = json_tokener_state_comment_end;
+ }
+ break;
+
+ case json_tokener_state_comment_eol:
+ {
+ /* Advance until we change state */
+ const char *case_start = str;
+ while (c != '\n')
+ {
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
+ {
+ printbuf_memappend_fast(tok->pb, case_start,
+ str - case_start);
+ goto out;
+ }
+ }
+ printbuf_memappend_fast(tok->pb, case_start, str - case_start);
+ MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
+ state = json_tokener_state_eatws;
+ }
+ break;
+
+ case json_tokener_state_comment_end:
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ if (c == '/')
+ {
+ MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
+ state = json_tokener_state_eatws;
+ }
+ else
+ {
+ state = json_tokener_state_comment;
+ }
+ break;
+
+ case json_tokener_state_string:
+ {
+ /* Advance until we change state */
+ const char *case_start = str;
+ while (1)
+ {
+ if (c == tok->quote_char)
+ {
+ printbuf_memappend_fast(tok->pb, case_start,
+ str - case_start);
+ current =
+ json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
+ if (current == NULL)
+ goto out;
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ break;
+ }
+ else if (c == '\\')
+ {
+ printbuf_memappend_fast(tok->pb, case_start,
+ str - case_start);
+ saved_state = json_tokener_state_string;
+ state = json_tokener_state_string_escape;
+ break;
+ }
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
+ {
+ printbuf_memappend_fast(tok->pb, case_start,
+ str - case_start);
+ goto out;
+ }
+ }
+ }
+ break;
+
+ case json_tokener_state_string_escape:
+ switch (c)
+ {
+ case '"':
+ case '\\':
+ case '/':
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ state = saved_state;
+ break;
+ case 'b':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'f':
+ if (c == 'b')
+ printbuf_memappend_fast(tok->pb, "\b", 1);
+ else if (c == 'n')
+ printbuf_memappend_fast(tok->pb, "\n", 1);
+ else if (c == 'r')
+ printbuf_memappend_fast(tok->pb, "\r", 1);
+ else if (c == 't')
+ printbuf_memappend_fast(tok->pb, "\t", 1);
+ else if (c == 'f')
+ printbuf_memappend_fast(tok->pb, "\f", 1);
+ state = saved_state;
+ break;
+ case 'u':
+ tok->ucs_char = 0;
+ tok->st_pos = 0;
+ state = json_tokener_state_escape_unicode;
+ break;
+ default: tok->err = json_tokener_error_parse_string; goto out;
+ }
+ break;
+
+ // ===================================================
+
+ case json_tokener_state_escape_unicode:
+ {
+ /* Handle a 4-byte \uNNNN sequence, or two sequences if a surrogate pair */
+ while (1)
+ {
+ if (!c || !strchr(json_hex_chars, c))
+ {
+ tok->err = json_tokener_error_parse_string;
+ goto out;
+ }
+ tok->ucs_char |=
+ ((unsigned int)jt_hexdigit(c) << ((3 - tok->st_pos) * 4));
+ tok->st_pos++;
+ if (tok->st_pos >= 4)
+ break;
+
+ (void)ADVANCE_CHAR(str, tok);
+ if (!PEEK_CHAR(c, tok))
+ {
+ /*
+ * We're out of characters in the current call to
+ * json_tokener_parse(), but a subsequent call might
+ * provide us with more, so leave our current state
+ * as-is (including tok->high_surrogate) and return.
+ */
+ goto out;
+ }
+ }
+ tok->st_pos = 0;
+
+ /* Now, we have a full \uNNNN sequence in tok->ucs_char */
+
+ /* If the *previous* sequence was a high surrogate ... */
+ if (tok->high_surrogate)
+ {
+ if (IS_LOW_SURROGATE(tok->ucs_char))
+ {
+ /* Recalculate the ucs_char, then fall thru to process normally */
+ tok->ucs_char = DECODE_SURROGATE_PAIR(tok->high_surrogate,
+ tok->ucs_char);
+ }
+ else
+ {
+ /* High surrogate was not followed by a low surrogate
+ * Replace the high and process the rest normally
+ */
+ printbuf_memappend_fast(tok->pb,
+ (char *)utf8_replacement_char, 3);
+ }
+ tok->high_surrogate = 0;
+ }
+
+ if (tok->ucs_char < 0x80)
+ {
+ unsigned char unescaped_utf[1];
+ unescaped_utf[0] = tok->ucs_char;
+ printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 1);
+ }
+ else if (tok->ucs_char < 0x800)
+ {
+ unsigned char unescaped_utf[2];
+ unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
+ unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
+ printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 2);
+ }
+ else if (IS_HIGH_SURROGATE(tok->ucs_char))
+ {
+ /*
+ * The next two characters should be \u, HOWEVER,
+ * we can't simply peek ahead here, because the
+ * characters we need might not be passed to us
+ * until a subsequent call to json_tokener_parse.
+ * Instead, transition throug a couple of states.
+ * (now):
+ * _escape_unicode => _unicode_need_escape
+ * (see a '\\' char):
+ * _unicode_need_escape => _unicode_need_u
+ * (see a 'u' char):
+ * _unicode_need_u => _escape_unicode
+ * ...and we'll end up back around here.
+ */
+ tok->high_surrogate = tok->ucs_char;
+ tok->ucs_char = 0;
+ state = json_tokener_state_escape_unicode_need_escape;
+ break;
+ }
+ else if (IS_LOW_SURROGATE(tok->ucs_char))
+ {
+ /* Got a low surrogate not preceded by a high */
+ printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3);
+ }
+ else if (tok->ucs_char < 0x10000)
+ {
+ unsigned char unescaped_utf[3];
+ unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
+ unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
+ unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
+ printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 3);
+ }
+ else if (tok->ucs_char < 0x110000)
+ {
+ unsigned char unescaped_utf[4];
+ unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
+ unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
+ unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
+ unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
+ printbuf_memappend_fast(tok->pb, (char *)unescaped_utf, 4);
+ }
+ else
+ {
+ /* Don't know what we got--insert the replacement char */
+ printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3);
+ }
+ state = saved_state; // i.e. _state_string or _state_object_field
+ }
+ break;
+
+ case json_tokener_state_escape_unicode_need_escape:
+ // We get here after processing a high_surrogate
+ // require a '\\' char
+ if (!c || c != '\\')
+ {
+ /* Got a high surrogate without another sequence following
+ * it. Put a replacement char in for the high surrogate
+ * and pop back up to _state_string or _state_object_field.
+ */
+ printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3);
+ tok->high_surrogate = 0;
+ tok->ucs_char = 0;
+ tok->st_pos = 0;
+ state = saved_state;
+ goto redo_char;
+ }
+ state = json_tokener_state_escape_unicode_need_u;
+ break;
+
+ case json_tokener_state_escape_unicode_need_u:
+ /* We already had a \ char, check that it's \u */
+ if (!c || c != 'u')
+ {
+ /* Got a high surrogate with some non-unicode escape
+ * sequence following it.
+ * Put a replacement char in for the high surrogate
+ * and handle the escape sequence normally.
+ */
+ printbuf_memappend_fast(tok->pb, (char *)utf8_replacement_char, 3);
+ tok->high_surrogate = 0;
+ tok->ucs_char = 0;
+ tok->st_pos = 0;
+ state = json_tokener_state_string_escape;
+ goto redo_char;
+ }
+ state = json_tokener_state_escape_unicode;
+ break;
+
+ // ===================================================
+
+ case json_tokener_state_boolean:
+ {
+ int size1, size2;
+ printbuf_memappend_fast(tok->pb, &c, 1);
+ size1 = json_min(tok->st_pos + 1, json_true_str_len);
+ size2 = json_min(tok->st_pos + 1, json_false_str_len);
+ if ((!(tok->flags & JSON_TOKENER_STRICT) &&
+ strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
+ (strncmp(json_true_str, tok->pb->buf, size1) == 0))
+ {
+ if (tok->st_pos == json_true_str_len)
+ {
+ current = json_object_new_boolean(1);
+ if (current == NULL)
+ goto out;
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ }
+ else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
+ strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
+ (strncmp(json_false_str, tok->pb->buf, size2) == 0))
+ {
+ if (tok->st_pos == json_false_str_len)
+ {
+ current = json_object_new_boolean(0);
+ if (current == NULL)
+ goto out;
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ }
+ else
+ {
+ tok->err = json_tokener_error_parse_boolean;
+ goto out;
+ }
+ tok->st_pos++;
+ }
+ break;
+
+ case json_tokener_state_number:
+ {
+ /* Advance until we change state */
+ const char *case_start = str;
+ int case_len = 0;
+ int is_exponent = 0;
+ int neg_sign_ok = 1;
+ int pos_sign_ok = 0;
+ if (printbuf_length(tok->pb) > 0)
+ {
+ /* We don't save all state from the previous incremental parse
+ so we need to re-generate it based on the saved string so far.
+ */
+ char *e_loc = strchr(tok->pb->buf, 'e');
+ if (!e_loc)
+ e_loc = strchr(tok->pb->buf, 'E');
+ if (e_loc)
+ {
+ char *last_saved_char =
+ &tok->pb->buf[printbuf_length(tok->pb) - 1];
+ is_exponent = 1;
+ pos_sign_ok = neg_sign_ok = 1;
+ /* If the "e" isn't at the end, we can't start with a '-' */
+ if (e_loc != last_saved_char)
+ {
+ neg_sign_ok = 0;
+ pos_sign_ok = 0;
+ }
+ // else leave it set to 1, i.e. start of the new input
+ }
+ }
+
+ while (c && ((c >= '0' && c <= '9') ||
+ (!is_exponent && (c == 'e' || c == 'E')) ||
+ (neg_sign_ok && c == '-') || (pos_sign_ok && c == '+') ||
+ (!tok->is_double && c == '.')))
+ {
+ pos_sign_ok = neg_sign_ok = 0;
+ ++case_len;
+
+ /* non-digit characters checks */
+ /* note: since the main loop condition to get here was
+ * an input starting with 0-9 or '-', we are
+ * protected from input starting with '.' or
+ * e/E.
+ */
+ switch (c)
+ {
+ case '.':
+ tok->is_double = 1;
+ pos_sign_ok = 1;
+ neg_sign_ok = 1;
+ break;
+ case 'e': /* FALLTHRU */
+ case 'E':
+ is_exponent = 1;
+ tok->is_double = 1;
+ /* the exponent part can begin with a negative sign */
+ pos_sign_ok = neg_sign_ok = 1;
+ break;
+ default: break;
+ }
+
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
+ {
+ printbuf_memappend_fast(tok->pb, case_start, case_len);
+ goto out;
+ }
+ }
+ /*
+ Now we know c isn't a valid number char, but check whether
+ it might have been intended to be, and return a potentially
+ more understandable error right away.
+ However, if we're at the top-level, use the number as-is
+ because c can be part of a new object to parse on the
+ next call to json_tokener_parse().
+ */
+ if (tok->depth > 0 && c != ',' && c != ']' && c != '}' && c != '/' &&
+ c != 'I' && c != 'i' && !isspace((unsigned char)c))
+ {
+ tok->err = json_tokener_error_parse_number;
+ goto out;
+ }
+ if (case_len > 0)
+ printbuf_memappend_fast(tok->pb, case_start, case_len);
+
+ // Check for -Infinity
+ if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
+ {
+ state = json_tokener_state_inf;
+ tok->st_pos = 0;
+ goto redo_char;
+ }
+ if (tok->is_double && !(tok->flags & JSON_TOKENER_STRICT))
+ {
+ /* Trim some chars off the end, to allow things
+ like "123e+" to parse ok. */
+ while (printbuf_length(tok->pb) > 1)
+ {
+ char last_char = tok->pb->buf[printbuf_length(tok->pb) - 1];
+ if (last_char != 'e' && last_char != 'E' &&
+ last_char != '-' && last_char != '+')
+ {
+ break;
+ }
+ tok->pb->buf[printbuf_length(tok->pb) - 1] = '\0';
+ printbuf_length(tok->pb)--;
+ }
+ }
+ }
+ {
+ int64_t num64;
+ uint64_t numuint64;
+ double numd;
+ if (!tok->is_double && tok->pb->buf[0] == '-' &&
+ json_parse_int64(tok->pb->buf, &num64) == 0)
+ {
+ current = json_object_new_int64(num64);
+ if (current == NULL)
+ goto out;
+ }
+ else if (!tok->is_double && tok->pb->buf[0] != '-' &&
+ json_parse_uint64(tok->pb->buf, &numuint64) == 0)
+ {
+ if (numuint64 && tok->pb->buf[0] == '0' &&
+ (tok->flags & JSON_TOKENER_STRICT))
+ {
+ tok->err = json_tokener_error_parse_number;
+ goto out;
+ }
+ if (numuint64 <= INT64_MAX)
+ {
+ num64 = (uint64_t)numuint64;
+ current = json_object_new_int64(num64);
+ if (current == NULL)
+ goto out;
+ }
+ else
+ {
+ current = json_object_new_uint64(numuint64);
+ if (current == NULL)
+ goto out;
+ }
+ }
+ else if (tok->is_double &&
+ json_tokener_parse_double(
+ tok->pb->buf, printbuf_length(tok->pb), &numd) == 0)
+ {
+ current = json_object_new_double_s(numd, tok->pb->buf);
+ if (current == NULL)
+ goto out;
+ }
+ else
+ {
+ tok->err = json_tokener_error_parse_number;
+ goto out;
+ }
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+ }
+ break;
+
+ case json_tokener_state_array_after_sep:
+ case json_tokener_state_array:
+ if (c == ']')
+ {
+ // Minimize memory usage; assume parsed objs are unlikely to be changed
+ json_object_array_shrink(current, 0);
+
+ if (state == json_tokener_state_array_after_sep &&
+ (tok->flags & JSON_TOKENER_STRICT))
+ {
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ }
+ else
+ {
+ if (tok->depth >= tok->max_depth - 1)
+ {
+ tok->err = json_tokener_error_depth;
+ goto out;
+ }
+ state = json_tokener_state_array_add;
+ tok->depth++;
+ json_tokener_reset_level(tok, tok->depth);
+ goto redo_char;
+ }
+ break;
+
+ case json_tokener_state_array_add:
+ if (json_object_array_add(current, obj) != 0)
+ goto out;
+ saved_state = json_tokener_state_array_sep;
state = json_tokener_state_eatws;
goto redo_char;
+
+ case json_tokener_state_array_sep:
+ if (c == ']')
+ {
+ // Minimize memory usage; assume parsed objs are unlikely to be changed
+ json_object_array_shrink(current, 0);
+
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ }
+ else if (c == ',')
+ {
+ saved_state = json_tokener_state_array_after_sep;
+ state = json_tokener_state_eatws;
+ }
+ else
+ {
+ tok->err = json_tokener_error_parse_array;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_object_field_start:
+ case json_tokener_state_object_field_start_after_sep:
+ if (c == '}')
+ {
+ if (state == json_tokener_state_object_field_start_after_sep &&
+ (tok->flags & JSON_TOKENER_STRICT))
+ {
+ tok->err = json_tokener_error_parse_unexpected;
+ goto out;
+ }
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ }
+ else if (c == '"' || c == '\'')
+ {
+ tok->quote_char = c;
+ printbuf_reset(tok->pb);
+ state = json_tokener_state_object_field;
+ }
+ else
+ {
+ tok->err = json_tokener_error_parse_object_key_name;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_object_field:
+ {
+ /* Advance until we change state */
+ const char *case_start = str;
+ while (1)
+ {
+ if (c == tok->quote_char)
+ {
+ printbuf_memappend_fast(tok->pb, case_start,
+ str - case_start);
+ obj_field_name = strdup(tok->pb->buf);
+ saved_state = json_tokener_state_object_field_end;
+ state = json_tokener_state_eatws;
+ break;
+ }
+ else if (c == '\\')
+ {
+ printbuf_memappend_fast(tok->pb, case_start,
+ str - case_start);
+ saved_state = json_tokener_state_object_field;
+ state = json_tokener_state_string_escape;
+ break;
+ }
+ if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
+ {
+ printbuf_memappend_fast(tok->pb, case_start,
+ str - case_start);
+ goto out;
+ }
+ }
}
- } else {
- tok->err = json_tokener_error_parse_null;
- goto out;
- }
- tok->st_pos++;
- }
- break;
-
- case json_tokener_state_comment_start:
- if(c == '*') {
- state = json_tokener_state_comment;
- } else if(c == '/') {
- state = json_tokener_state_comment_eol;
- } else {
- tok->err = json_tokener_error_parse_comment;
- goto out;
- }
- printbuf_memappend_fast(tok->pb, &c, 1);
- break;
-
- case json_tokener_state_comment:
- {
- /* Advance until we change state */
- const char *case_start = str;
- while(c != '*') {
- if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
- printbuf_memappend_fast(tok->pb, case_start, str-case_start);
- goto out;
- }
- }
- printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start);
- state = json_tokener_state_comment_end;
- }
- break;
-
- case json_tokener_state_comment_eol:
- {
- /* Advance until we change state */
- const char *case_start = str;
- while(c != '\n') {
- if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
- printbuf_memappend_fast(tok->pb, case_start, str-case_start);
- goto out;
- }
- }
- printbuf_memappend_fast(tok->pb, case_start, str-case_start);
- MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
- state = json_tokener_state_eatws;
- }
- break;
-
- case json_tokener_state_comment_end:
- printbuf_memappend_fast(tok->pb, &c, 1);
- if(c == '/') {
- MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
- state = json_tokener_state_eatws;
- } else {
- state = json_tokener_state_comment;
- }
- break;
-
- case json_tokener_state_string:
- {
- /* Advance until we change state */
- const char *case_start = str;
- while(1) {
- if(c == tok->quote_char) {
- printbuf_memappend_fast(tok->pb, case_start, str-case_start);
- current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
- if(current == NULL)
- goto out;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- break;
- } else if(c == '\\') {
- printbuf_memappend_fast(tok->pb, case_start, str-case_start);
- saved_state = json_tokener_state_string;
- state = json_tokener_state_string_escape;
- break;
- }
- if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
- printbuf_memappend_fast(tok->pb, case_start, str-case_start);
- goto out;
- }
- }
- }
- break;
-
- case json_tokener_state_string_escape:
- switch(c) {
- case '"':
- case '\\':
- case '/':
- printbuf_memappend_fast(tok->pb, &c, 1);
- state = saved_state;
- break;
- case 'b':
- case 'n':
- case 'r':
- case 't':
- case 'f':
- if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1);
- else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1);
- else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1);
- else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1);
- else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1);
- state = saved_state;
- break;
- case 'u':
- tok->ucs_char = 0;
- tok->st_pos = 0;
- state = json_tokener_state_escape_unicode;
- break;
- default:
- tok->err = json_tokener_error_parse_string;
- goto out;
- }
- break;
-
- case json_tokener_state_escape_unicode:
- {
- unsigned int got_hi_surrogate = 0;
-
- /* Handle a 4-byte sequence, or two sequences if a surrogate pair */
- while(1) {
- if (c && strchr(json_hex_chars, c)) {
- tok->ucs_char += ((unsigned int)jt_hexdigit(c) << ((3-tok->st_pos++)*4));
- if(tok->st_pos == 4) {
- unsigned char unescaped_utf[4];
-
- if (got_hi_surrogate) {
- if (IS_LOW_SURROGATE(tok->ucs_char)) {
- /* Recalculate the ucs_char, then fall thru to process normally */
- tok->ucs_char = DECODE_SURROGATE_PAIR(got_hi_surrogate, tok->ucs_char);
- } else {
- /* Hi surrogate was not followed by a low surrogate */
- /* Replace the hi and process the rest normally */
- printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
- }
- got_hi_surrogate = 0;
- }
-
- if (tok->ucs_char < 0x80) {
- unescaped_utf[0] = tok->ucs_char;
- printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
- } else if (tok->ucs_char < 0x800) {
- unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
- unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
- printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
- } else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
- /* Got a high surrogate. Remember it and look for the
- * the beginning of another sequence, which should be the
- * low surrogate.
- */
- got_hi_surrogate = tok->ucs_char;
- /* Not at end, and the next two chars should be "\u" */
- if ((len == -1 || len > (tok->char_offset + 2)) &&
- // str[0] != '0' && // implied by json_hex_chars, above.
- (str[1] == '\\') &&
- (str[2] == 'u'))
- {
- /* Advance through the 16 bit surrogate, and move on to the
- * next sequence. The next step is to process the following
- * characters.
- */
- if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
- printbuf_memappend_fast(tok->pb,
- (char*) utf8_replacement_char, 3);
- }
- /* Advance to the first char of the next sequence and
- * continue processing with the next sequence.
- */
- if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
- printbuf_memappend_fast(tok->pb,
- (char*) utf8_replacement_char, 3);
- goto out;
- }
- tok->ucs_char = 0;
- tok->st_pos = 0;
- continue; /* other json_tokener_state_escape_unicode */
- } else {
- /* Got a high surrogate without another sequence following
- * it. Put a replacement char in for the hi surrogate
- * and pretend we finished.
- */
- printbuf_memappend_fast(tok->pb,
- (char*) utf8_replacement_char, 3);
- }
- } else if (IS_LOW_SURROGATE(tok->ucs_char)) {
- /* Got a low surrogate not preceded by a high */
- printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
- } else if (tok->ucs_char < 0x10000) {
- unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
- unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
- unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
- printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 3);
- } else if (tok->ucs_char < 0x110000) {
- unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
- unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
- unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
- unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
- printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 4);
- } else {
- /* Don't know what we got--insert the replacement char */
- printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
- }
- state = saved_state;
break;
- }
- } else {
- tok->err = json_tokener_error_parse_string;
- goto out;
- }
- if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
- if (got_hi_surrogate) /* Clean up any pending chars */
- printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
- goto out;
- }
- }
- }
- break;
-
- case json_tokener_state_boolean:
- {
- int size1, size2;
- printbuf_memappend_fast(tok->pb, &c, 1);
- size1 = json_min(tok->st_pos+1, json_true_str_len);
- size2 = json_min(tok->st_pos+1, json_false_str_len);
- if((!(tok->flags & JSON_TOKENER_STRICT) &&
- strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
- || (strncmp(json_true_str, tok->pb->buf, size1) == 0)
- ) {
- if(tok->st_pos == json_true_str_len) {
- current = json_object_new_boolean(1);
- if(current == NULL)
- goto out;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- goto redo_char;
- }
- } else if((!(tok->flags & JSON_TOKENER_STRICT) &&
- strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
- || (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
- if(tok->st_pos == json_false_str_len) {
- current = json_object_new_boolean(0);
- if(current == NULL)
- goto out;
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- goto redo_char;
- }
- } else {
- tok->err = json_tokener_error_parse_boolean;
- goto out;
- }
- tok->st_pos++;
- }
- break;
-
- case json_tokener_state_number:
- {
- /* Advance until we change state */
- const char *case_start = str;
- int case_len=0;
- int is_exponent=0;
- int negativesign_next_possible_location=1;
- while(c && strchr(json_number_chars, c)) {
- ++case_len;
-
- /* non-digit characters checks */
- /* note: since the main loop condition to get here was
- an input starting with 0-9 or '-', we are
- protected from input starting with '.' or
- e/E. */
- if (c == '.') {
- if (tok->is_double != 0) {
- /* '.' can only be found once, and out of the exponent part.
- Thus, if the input is already flagged as double, it
- is invalid. */
- tok->err = json_tokener_error_parse_number;
- goto out;
- }
- tok->is_double = 1;
- }
- if (c == 'e' || c == 'E') {
- if (is_exponent != 0) {
- /* only one exponent possible */
- tok->err = json_tokener_error_parse_number;
- goto out;
- }
- is_exponent = 1;
- tok->is_double = 1;
- /* the exponent part can begin with a negative sign */
- negativesign_next_possible_location = case_len + 1;
- }
- if (c == '-' && case_len != negativesign_next_possible_location) {
- /* If the negative sign is not where expected (ie
- start of input or start of exponent part), the
- input is invalid. */
- tok->err = json_tokener_error_parse_number;
- goto out;
- }
-
- if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
- printbuf_memappend_fast(tok->pb, case_start, case_len);
- goto out;
- }
- }
- if (case_len>0)
- printbuf_memappend_fast(tok->pb, case_start, case_len);
-
- // Check for -Infinity
- if (tok->pb->buf[0] == '-' && case_len <= 1 &&
- (c == 'i' || c == 'I'))
- {
- state = json_tokener_state_inf;
- tok->st_pos = 0;
- goto redo_char;
- }
- }
- {
- int64_t num64;
- double numd;
- if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
- if (num64 && tok->pb->buf[0]=='0' &&
- (tok->flags & JSON_TOKENER_STRICT)) {
- /* in strict mode, number must not start with 0 */
- tok->err = json_tokener_error_parse_number;
- goto out;
- }
- current = json_object_new_int64(num64);
- if(current == NULL)
- goto out;
- }
- else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
- {
- current = json_object_new_double_s(numd, tok->pb->buf);
- if(current == NULL)
- goto out;
- } else {
- tok->err = json_tokener_error_parse_number;
- goto out;
- }
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- goto redo_char;
- }
- break;
-
- case json_tokener_state_array_after_sep:
- case json_tokener_state_array:
- if(c == ']') {
- if (state == json_tokener_state_array_after_sep &&
- (tok->flags & JSON_TOKENER_STRICT))
- {
- tok->err = json_tokener_error_parse_unexpected;
- goto out;
- }
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else {
- if(tok->depth >= tok->max_depth-1) {
- tok->err = json_tokener_error_depth;
- goto out;
- }
- state = json_tokener_state_array_add;
- tok->depth++;
- json_tokener_reset_level(tok, tok->depth);
- goto redo_char;
- }
- break;
-
- case json_tokener_state_array_add:
- if( json_object_array_add(current, obj) != 0 )
- goto out;
- saved_state = json_tokener_state_array_sep;
- state = json_tokener_state_eatws;
- goto redo_char;
-
- case json_tokener_state_array_sep:
- if(c == ']') {
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else if(c == ',') {
- saved_state = json_tokener_state_array_after_sep;
- state = json_tokener_state_eatws;
- } else {
- tok->err = json_tokener_error_parse_array;
- goto out;
- }
- break;
-
- case json_tokener_state_object_field_start:
- case json_tokener_state_object_field_start_after_sep:
- if(c == '}') {
- if (state == json_tokener_state_object_field_start_after_sep &&
- (tok->flags & JSON_TOKENER_STRICT))
- {
- tok->err = json_tokener_error_parse_unexpected;
- goto out;
- }
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else if (c == '"' || c == '\'') {
- tok->quote_char = c;
- printbuf_reset(tok->pb);
- state = json_tokener_state_object_field;
- } else {
- tok->err = json_tokener_error_parse_object_key_name;
- goto out;
- }
- break;
-
- case json_tokener_state_object_field:
- {
- /* Advance until we change state */
- const char *case_start = str;
- while(1) {
- if(c == tok->quote_char) {
- printbuf_memappend_fast(tok->pb, case_start, str-case_start);
- obj_field_name = strdup(tok->pb->buf);
- saved_state = json_tokener_state_object_field_end;
- state = json_tokener_state_eatws;
- break;
- } else if(c == '\\') {
- printbuf_memappend_fast(tok->pb, case_start, str-case_start);
- saved_state = json_tokener_state_object_field;
- state = json_tokener_state_string_escape;
- break;
- }
- if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
- printbuf_memappend_fast(tok->pb, case_start, str-case_start);
- goto out;
- }
- }
- }
- break;
-
- case json_tokener_state_object_field_end:
- if(c == ':') {
- saved_state = json_tokener_state_object_value;
- state = json_tokener_state_eatws;
- } else {
- tok->err = json_tokener_error_parse_object_key_sep;
- goto out;
- }
- break;
-
- case json_tokener_state_object_value:
- if(tok->depth >= tok->max_depth-1) {
- tok->err = json_tokener_error_depth;
- goto out;
- }
- state = json_tokener_state_object_value_add;
- tok->depth++;
- json_tokener_reset_level(tok, tok->depth);
- goto redo_char;
-
- case json_tokener_state_object_value_add:
- json_object_object_add(current, obj_field_name, obj);
- free(obj_field_name);
- obj_field_name = NULL;
- saved_state = json_tokener_state_object_sep;
- state = json_tokener_state_eatws;
- goto redo_char;
-
- case json_tokener_state_object_sep:
- /* { */
- if(c == '}') {
- saved_state = json_tokener_state_finish;
- state = json_tokener_state_eatws;
- } else if(c == ',') {
- saved_state = json_tokener_state_object_field_start_after_sep;
- state = json_tokener_state_eatws;
- } else {
- tok->err = json_tokener_error_parse_object_value_sep;
- goto out;
- }
- break;
-
- }
- if (!ADVANCE_CHAR(str, tok))
- goto out;
- } /* while(PEEK_CHAR) */
-
- out:
- if (c &&
- (state == json_tokener_state_finish) &&
- (tok->depth == 0) &&
- (tok->flags & JSON_TOKENER_STRICT)) {
- /* unexpected char after JSON data */
- tok->err = json_tokener_error_parse_unexpected;
- }
- if (!c) { /* We hit an eof char (0) */
- if(state != json_tokener_state_finish &&
- saved_state != json_tokener_state_finish)
- tok->err = json_tokener_error_parse_eof;
- }
+
+ case json_tokener_state_object_field_end:
+ if (c == ':')
+ {
+ saved_state = json_tokener_state_object_value;
+ state = json_tokener_state_eatws;
+ }
+ else
+ {
+ tok->err = json_tokener_error_parse_object_key_sep;
+ goto out;
+ }
+ break;
+
+ case json_tokener_state_object_value:
+ if (tok->depth >= tok->max_depth - 1)
+ {
+ tok->err = json_tokener_error_depth;
+ goto out;
+ }
+ state = json_tokener_state_object_value_add;
+ tok->depth++;
+ json_tokener_reset_level(tok, tok->depth);
+ goto redo_char;
+
+ case json_tokener_state_object_value_add:
+ json_object_object_add(current, obj_field_name, obj);
+ free(obj_field_name);
+ obj_field_name = NULL;
+ saved_state = json_tokener_state_object_sep;
+ state = json_tokener_state_eatws;
+ goto redo_char;
+
+ case json_tokener_state_object_sep:
+ /* { */
+ if (c == '}')
+ {
+ saved_state = json_tokener_state_finish;
+ state = json_tokener_state_eatws;
+ }
+ else if (c == ',')
+ {
+ saved_state = json_tokener_state_object_field_start_after_sep;
+ state = json_tokener_state_eatws;
+ }
+ else
+ {
+ tok->err = json_tokener_error_parse_object_value_sep;
+ goto out;
+ }
+ break;
+ }
+ (void)ADVANCE_CHAR(str, tok);
+ if (!c) // This is the char *before* advancing
+ break;
+ } /* while(PEEK_CHAR) */
+
+out:
+ if ((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && (nBytes != 0))
+ {
+ tok->err = json_tokener_error_parse_utf8_string;
+ }
+ if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
+ (tok->flags & (JSON_TOKENER_STRICT | JSON_TOKENER_ALLOW_TRAILING_CHARS)) ==
+ JSON_TOKENER_STRICT)
+ {
+ /* unexpected char after JSON data */
+ tok->err = json_tokener_error_parse_unexpected;
+ }
+ if (!c)
+ {
+ /* We hit an eof char (0) */
+ if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
+ tok->err = json_tokener_error_parse_eof;
+ }
#ifdef HAVE_USELOCALE
- uselocale(oldlocale);
- freelocale(newloc);
+ uselocale(oldlocale);
+ freelocale(newloc);
#elif defined(HAVE_SETLOCALE)
- setlocale(LC_NUMERIC, oldlocale);
- free(oldlocale);
+ setlocale(LC_NUMERIC, oldlocale);
+ free(oldlocale);
#endif
- if (tok->err == json_tokener_success)
- {
- json_object *ret = json_object_get(current);
- int ii;
-
- /* Partially reset, so we parse additional objects on subsequent calls. */
- for(ii = tok->depth; ii >= 0; ii--)
- json_tokener_reset_level(tok, ii);
- return ret;
- }
-
- MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
- json_tokener_errors[tok->err], tok->char_offset);
- return NULL;
+ if (tok->err == json_tokener_success)
+ {
+ json_object *ret = json_object_get(current);
+ int ii;
+
+ /* Partially reset, so we parse additional objects on subsequent calls. */
+ for (ii = tok->depth; ii >= 0; ii--)
+ json_tokener_reset_level(tok, ii);
+ return ret;
+ }
+
+ MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
+ tok->char_offset);
+ return NULL;
+}
+
+static json_bool json_tokener_validate_utf8(const char c, unsigned int *nBytes)
+{
+ unsigned char chr = c;
+ if (*nBytes == 0)
+ {
+ if (chr >= 0x80)
+ {
+ if ((chr & 0xe0) == 0xc0)
+ *nBytes = 1;
+ else if ((chr & 0xf0) == 0xe0)
+ *nBytes = 2;
+ else if ((chr & 0xf8) == 0xf0)
+ *nBytes = 3;
+ else
+ return 0;
+ }
+ }
+ else
+ {
+ if ((chr & 0xC0) != 0x80)
+ return 0;
+ (*nBytes)--;
+ }
+ return 1;
}
void json_tokener_set_flags(struct json_tokener *tok, int flags)
{
tok->flags = flags;
}
+
+size_t json_tokener_get_parse_end(struct json_tokener *tok)
+{
+ assert(tok->char_offset >= 0); /* Drop this line when char_offset becomes a size_t */
+ return (size_t)tok->char_offset;
+}
+
+static int json_tokener_parse_double(const char *buf, int len, double *retval)
+{
+ char *end;
+ *retval = strtod(buf, &end);
+ if (buf + len == end)
+ return 0; // It worked
+ return 1;
+}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_tokener.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_tokener.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_tokener.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_tokener.h 2022-04-15 07:49:22.000000000 +0000
@@ -16,80 +16,125 @@
#ifndef _json_tokener_h_
#define _json_tokener_h_
-#include
#include "json_object.h"
+#include
#ifdef __cplusplus
extern "C" {
#endif
-enum json_tokener_error {
- json_tokener_success,
- json_tokener_continue,
- json_tokener_error_depth,
- json_tokener_error_parse_eof,
- json_tokener_error_parse_unexpected,
- json_tokener_error_parse_null,
- json_tokener_error_parse_boolean,
- json_tokener_error_parse_number,
- json_tokener_error_parse_array,
- json_tokener_error_parse_object_key_name,
- json_tokener_error_parse_object_key_sep,
- json_tokener_error_parse_object_value_sep,
- json_tokener_error_parse_string,
- json_tokener_error_parse_comment,
- json_tokener_error_size
+enum json_tokener_error
+{
+ json_tokener_success,
+ json_tokener_continue,
+ json_tokener_error_depth,
+ json_tokener_error_parse_eof,
+ json_tokener_error_parse_unexpected,
+ json_tokener_error_parse_null,
+ json_tokener_error_parse_boolean,
+ json_tokener_error_parse_number,
+ json_tokener_error_parse_array,
+ json_tokener_error_parse_object_key_name,
+ json_tokener_error_parse_object_key_sep,
+ json_tokener_error_parse_object_value_sep,
+ json_tokener_error_parse_string,
+ json_tokener_error_parse_comment,
+ json_tokener_error_parse_utf8_string,
+ json_tokener_error_size
};
-enum json_tokener_state {
- json_tokener_state_eatws,
- json_tokener_state_start,
- json_tokener_state_finish,
- json_tokener_state_null,
- json_tokener_state_comment_start,
- json_tokener_state_comment,
- json_tokener_state_comment_eol,
- json_tokener_state_comment_end,
- json_tokener_state_string,
- json_tokener_state_string_escape,
- json_tokener_state_escape_unicode,
- json_tokener_state_boolean,
- json_tokener_state_number,
- json_tokener_state_array,
- json_tokener_state_array_add,
- json_tokener_state_array_sep,
- json_tokener_state_object_field_start,
- json_tokener_state_object_field,
- json_tokener_state_object_field_end,
- json_tokener_state_object_value,
- json_tokener_state_object_value_add,
- json_tokener_state_object_sep,
- json_tokener_state_array_after_sep,
- json_tokener_state_object_field_start_after_sep,
- json_tokener_state_inf
+/**
+ * @deprecated Don't use this outside of json_tokener.c, it will be made private in a future release.
+ */
+enum json_tokener_state
+{
+ json_tokener_state_eatws,
+ json_tokener_state_start,
+ json_tokener_state_finish,
+ json_tokener_state_null,
+ json_tokener_state_comment_start,
+ json_tokener_state_comment,
+ json_tokener_state_comment_eol,
+ json_tokener_state_comment_end,
+ json_tokener_state_string,
+ json_tokener_state_string_escape,
+ json_tokener_state_escape_unicode,
+ json_tokener_state_escape_unicode_need_escape,
+ json_tokener_state_escape_unicode_need_u,
+ json_tokener_state_boolean,
+ json_tokener_state_number,
+ json_tokener_state_array,
+ json_tokener_state_array_add,
+ json_tokener_state_array_sep,
+ json_tokener_state_object_field_start,
+ json_tokener_state_object_field,
+ json_tokener_state_object_field_end,
+ json_tokener_state_object_value,
+ json_tokener_state_object_value_add,
+ json_tokener_state_object_sep,
+ json_tokener_state_array_after_sep,
+ json_tokener_state_object_field_start_after_sep,
+ json_tokener_state_inf
};
+/**
+ * @deprecated Don't use this outside of json_tokener.c, it will be made private in a future release.
+ */
struct json_tokener_srec
{
- enum json_tokener_state state, saved_state;
- struct json_object *obj;
- struct json_object *current;
- char *obj_field_name;
+ enum json_tokener_state state, saved_state;
+ struct json_object *obj;
+ struct json_object *current;
+ char *obj_field_name;
};
#define JSON_TOKENER_DEFAULT_DEPTH 32
+/**
+ * Internal state of the json parser.
+ * Do not access any fields of this structure directly.
+ * Its definition is published due to historical limitations
+ * in the json tokener API, and will be changed to be an opaque
+ * type in the future.
+ */
struct json_tokener
{
- char *str;
- struct printbuf *pb;
- int max_depth, depth, is_double, st_pos, char_offset;
- enum json_tokener_error err;
- unsigned int ucs_char;
- char quote_char;
- struct json_tokener_srec *stack;
- int flags;
+ /**
+ * @deprecated Do not access any of these fields outside of json_tokener.c
+ */
+ char *str;
+ struct printbuf *pb;
+ int max_depth, depth, is_double, st_pos;
+ /**
+ * @deprecated See json_tokener_get_parse_end() instead.
+ */
+ int char_offset;
+ /**
+ * @deprecated See json_tokener_get_error() instead.
+ */
+ enum json_tokener_error err;
+ unsigned int ucs_char, high_surrogate;
+ char quote_char;
+ struct json_tokener_srec *stack;
+ int flags;
};
+
+/**
+ * Return the offset of the byte after the last byte parsed
+ * relative to the start of the most recent string passed in
+ * to json_tokener_parse_ex(). i.e. this is where parsing
+ * would start again if the input contains another JSON object
+ * after the currently parsed one.
+ *
+ * Note that when multiple parse calls are issued, this is *not* the
+ * total number of characters parsed.
+ *
+ * In the past this would have been accessed as tok->char_offset.
+ *
+ * See json_tokener_parse_ex() for an example of how to use this.
+ */
+JSON_EXPORT size_t json_tokener_get_parse_end(struct json_tokener *tok);
+
/**
* @deprecated Unused in json-c code
*/
@@ -101,11 +146,36 @@
* restrictive from one release to the next, causing your
* code to fail on previously working input.
*
+ * Note that setting this will also effectively disable parsing
+ * of multiple json objects in a single character stream
+ * (e.g. {"foo":123}{"bar":234}); if you want to allow that
+ * also set JSON_TOKENER_ALLOW_TRAILING_CHARS
+ *
+ * This flag is not set by default.
+ *
+ * @see json_tokener_set_flags()
+ */
+#define JSON_TOKENER_STRICT 0x01
+
+/**
+ * Use with JSON_TOKENER_STRICT to allow trailing characters after the
+ * first parsed object.
+ *
+ * @see json_tokener_set_flags()
+ */
+#define JSON_TOKENER_ALLOW_TRAILING_CHARS 0x02
+
+/**
+ * Cause json_tokener_parse_ex() to validate that input is UTF8.
+ * If this flag is specified and validation fails, then
+ * json_tokener_get_error(tok) will return
+ * json_tokener_error_parse_utf8_string
+ *
* This flag is not set by default.
*
* @see json_tokener_set_flags()
*/
-#define JSON_TOKENER_STRICT 0x01
+#define JSON_TOKENER_VALIDATE_UTF8 0x10
/**
* Given an error previously returned by json_tokener_get_error(),
@@ -113,7 +183,7 @@
*
* @return a generic error message is returned if an invalid error value is provided.
*/
-const char *json_tokener_error_desc(enum json_tokener_error jerr);
+JSON_EXPORT const char *json_tokener_error_desc(enum json_tokener_error jerr);
/**
* Retrieve the error caused by the last call to json_tokener_parse_ex(),
@@ -122,16 +192,50 @@
* When parsing a JSON string in pieces, if the tokener is in the middle
* of parsing this will return json_tokener_continue.
*
- * See also json_tokener_error_desc().
+ * @see json_tokener_error_desc().
*/
JSON_EXPORT enum json_tokener_error json_tokener_get_error(struct json_tokener *tok);
-JSON_EXPORT struct json_tokener* json_tokener_new(void);
-JSON_EXPORT struct json_tokener* json_tokener_new_ex(int depth);
+/**
+ * Allocate a new json_tokener.
+ * When done using that to parse objects, free it with json_tokener_free().
+ * See json_tokener_parse_ex() for usage details.
+ */
+JSON_EXPORT struct json_tokener *json_tokener_new(void);
+
+/**
+ * Allocate a new json_tokener with a custom max nesting depth.
+ * @see JSON_TOKENER_DEFAULT_DEPTH
+ */
+JSON_EXPORT struct json_tokener *json_tokener_new_ex(int depth);
+
+/**
+ * Free a json_tokener previously allocated with json_tokener_new().
+ */
JSON_EXPORT void json_tokener_free(struct json_tokener *tok);
+
+/**
+ * Reset the state of a json_tokener, to prepare to parse a
+ * brand new JSON object.
+ */
JSON_EXPORT void json_tokener_reset(struct json_tokener *tok);
-JSON_EXPORT struct json_object* json_tokener_parse(const char *str);
-JSON_EXPORT struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
+
+/**
+ * Parse a json_object out of the string `str`.
+ *
+ * If you need more control over how the parsing occurs,
+ * see json_tokener_parse_ex().
+ */
+JSON_EXPORT struct json_object *json_tokener_parse(const char *str);
+
+/**
+ * Parser a json_object out of the string `str`, but if it fails
+ * return the error in `*error`.
+ * @see json_tokener_parse()
+ * @see json_tokener_parse_ex()
+ */
+JSON_EXPORT struct json_object *json_tokener_parse_verbose(const char *str,
+ enum json_tokener_error *error);
/**
* Set flags that control how parsing will be done.
@@ -151,26 +255,32 @@
*
* If json_tokener_parse_ex() returns NULL and the error is anything other than
* json_tokener_continue, a fatal error has occurred and parsing must be
- * halted. Then, the tok object must not be reused until json_tokener_reset() is
- * called.
+ * halted. Then, the tok object must not be reused until json_tokener_reset()
+ * is called.
*
* When a valid JSON value is parsed, a non-NULL json_object will be
- * returned. Also, json_tokener_get_error() will return json_tokener_success.
- * Be sure to check the type with json_object_is_type() or
- * json_object_get_type() before using the object.
+ * returned, with a reference count of one which belongs to the caller. Also,
+ * json_tokener_get_error() will return json_tokener_success. Be sure to check
+ * the type with json_object_is_type() or json_object_get_type() before using
+ * the object.
*
- * @b XXX this shouldn't use internal fields:
* Trailing characters after the parsed value do not automatically cause an
* error. It is up to the caller to decide whether to treat this as an
* error or to handle the additional characters, perhaps by parsing another
* json value starting from that point.
*
- * Extra characters can be detected by comparing the tok->char_offset against
+ * If the caller knows that they are at the end of their input, the length
+ * passed MUST include the final '\0' character, so values with no inherent
+ * end (i.e. numbers) can be properly parsed, rather than just returning
+ * json_tokener_continue.
+ *
+ * Extra characters can be detected by comparing the value returned by
+ * json_tokener_get_parse_end() against
* the length of the last len parameter passed in.
*
* The tokener does \b not maintain an internal buffer so the caller is
- * responsible for calling json_tokener_parse_ex with an appropriate str
- * parameter starting with the extra characters.
+ * responsible for a subsequent call to json_tokener_parse_ex with an
+ * appropriate str parameter starting with the extra characters.
*
* This interface is presently not 64-bit clean due to the int len argument
* so the function limits the maximum string size to INT32_MAX (2GB).
@@ -186,6 +296,8 @@
do {
mystring = ... // get JSON string, e.g. read from file, etc...
stringlen = strlen(mystring);
+ if (end_of_input)
+ stringlen++; // Include the '\0' if we know we're at the end of input
jobj = json_tokener_parse_ex(tok, mystring, stringlen);
} while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
if (jerr != json_tokener_success)
@@ -193,7 +305,7 @@
fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
// Handle errors, as appropriate for your application.
}
-if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
+if (json_tokener_get_parse_end(tok) < stringlen)
{
// Handle extra characters after parsed object as desired.
// e.g. issue an error, parse another object from that point, etc...
@@ -206,8 +318,8 @@
* @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated.
* @param len the length of str
*/
-JSON_EXPORT struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
- const char *str, int len);
+JSON_EXPORT struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str,
+ int len);
#ifdef __cplusplus
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_types.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_types.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_types.h 1970-01-01 00:00:00.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_types.h 2022-04-15 07:49:21.000000000 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2020 Eric Hawicz
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See COPYING for details.
+ */
+
+#ifndef _json_types_h_
+#define _json_types_h_
+
+/**
+ * @file
+ * @brief Basic types used in a few places in json-c, but you should include "json_object.h" instead.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef JSON_EXPORT
+#if defined(_MSC_VER)
+#define JSON_EXPORT __declspec(dllexport)
+#else
+#define JSON_EXPORT extern
+#endif
+#endif
+
+struct printbuf;
+
+/**
+ * A structure to use with json_object_object_foreachC() loops.
+ * Contains key, val and entry members.
+ */
+struct json_object_iter
+{
+ char *key;
+ struct json_object *val;
+ struct lh_entry *entry;
+};
+typedef struct json_object_iter json_object_iter;
+
+typedef int json_bool;
+
+/**
+ * @brief The core type for all type of JSON objects handled by json-c
+ */
+typedef struct json_object json_object;
+
+/**
+ * Type of custom user delete functions. See json_object_set_serializer.
+ */
+typedef void(json_object_delete_fn)(struct json_object *jso, void *userdata);
+
+/**
+ * Type of a custom serialization function. See json_object_set_serializer.
+ */
+typedef int(json_object_to_json_string_fn)(struct json_object *jso, struct printbuf *pb, int level,
+ int flags);
+
+/* supported object types */
+
+typedef enum json_type
+{
+ /* If you change this, be sure to update json_type_to_name() too */
+ json_type_null,
+ json_type_boolean,
+ json_type_double,
+ json_type_int,
+ json_type_object,
+ json_type_array,
+ json_type_string
+} json_type;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_util.c thunderbird-91.8.1+build1/comm/third_party/json-c/json_util.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_util.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_util.c 2022-04-15 07:49:21.000000000 +0000
@@ -14,13 +14,13 @@
#include "strerror_override.h"
+#include
+#include
#include
+#include
#include
#include
-#include
-#include
#include
-#include
#ifdef HAVE_SYS_TYPES_H
#include
@@ -35,31 +35,27 @@
#endif /* HAVE_FCNTL_H */
#ifdef HAVE_UNISTD_H
-# include
+#include
#endif /* HAVE_UNISTD_H */
#ifdef WIN32
-# if MSC_VER < 1800
-/* strtoll is available only since Visual Studio 2013 */
-# define strtoll _strtoi64
-# endif
-# define WIN32_LEAN_AND_MEAN
-# include
-# include
+#define WIN32_LEAN_AND_MEAN
+#include
+#include
#endif /* defined(WIN32) */
#if !defined(HAVE_OPEN) && defined(WIN32)
-# define open _open
+#define open _open
#endif
#include "snprintf_compat.h"
#include "debug.h"
-#include "printbuf.h"
#include "json_inttypes.h"
#include "json_object.h"
#include "json_tokener.h"
#include "json_util.h"
+#include "printbuf.h"
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename);
@@ -81,43 +77,74 @@
va_end(ap);
}
-struct json_object* json_object_from_fd(int fd)
+struct json_object *json_object_from_fd(int fd)
{
- struct printbuf *pb;
- struct json_object *obj;
- char buf[JSON_FILE_BUF_SIZE];
- int ret;
-
- if(!(pb = printbuf_new())) {
- _json_c_set_last_err("json_object_from_file: printbuf_new failed\n");
- return NULL;
- }
- while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
- printbuf_memappend(pb, buf, ret);
- }
- if(ret < 0) {
- _json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd, strerror(errno));
- printbuf_free(pb);
- return NULL;
- }
- obj = json_tokener_parse(pb->buf);
- printbuf_free(pb);
- return obj;
-}
-
-struct json_object* json_object_from_file(const char *filename)
-{
- struct json_object *obj;
- int fd;
-
- if((fd = open(filename, O_RDONLY)) < 0) {
- _json_c_set_last_err("json_object_from_file: error opening file %s: %s\n",
- filename, strerror(errno));
- return NULL;
- }
- obj = json_object_from_fd(fd);
- close(fd);
- return obj;
+ return json_object_from_fd_ex(fd, -1);
+}
+struct json_object *json_object_from_fd_ex(int fd, int in_depth)
+{
+ struct printbuf *pb;
+ struct json_object *obj;
+ char buf[JSON_FILE_BUF_SIZE];
+ int ret;
+ int depth = JSON_TOKENER_DEFAULT_DEPTH;
+ json_tokener *tok;
+
+ if (!(pb = printbuf_new()))
+ {
+ _json_c_set_last_err("json_object_from_file: printbuf_new failed\n");
+ return NULL;
+ }
+
+ if (in_depth != -1)
+ depth = in_depth;
+ tok = json_tokener_new_ex(depth);
+ if (!tok)
+ {
+ _json_c_set_last_err(
+ "json_object_from_fd: unable to allocate json_tokener(depth=%d): %s\n", depth,
+ strerror(errno));
+ printbuf_free(pb);
+ return NULL;
+ }
+
+ while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0)
+ {
+ printbuf_memappend(pb, buf, ret);
+ }
+ if (ret < 0)
+ {
+ _json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd,
+ strerror(errno));
+ json_tokener_free(tok);
+ printbuf_free(pb);
+ return NULL;
+ }
+
+ obj = json_tokener_parse_ex(tok, pb->buf, printbuf_length(pb));
+ if (obj == NULL)
+ _json_c_set_last_err("json_tokener_parse_ex failed: %s\n",
+ json_tokener_error_desc(json_tokener_get_error(tok)));
+
+ json_tokener_free(tok);
+ printbuf_free(pb);
+ return obj;
+}
+
+struct json_object *json_object_from_file(const char *filename)
+{
+ struct json_object *obj;
+ int fd;
+
+ if ((fd = open(filename, O_RDONLY)) < 0)
+ {
+ _json_c_set_last_err("json_object_from_file: error opening file %s: %s\n", filename,
+ strerror(errno));
+ return NULL;
+ }
+ obj = json_object_from_fd(fd);
+ close(fd);
+ return obj;
}
/* extended "format and write to file" function */
@@ -127,14 +154,16 @@
int fd, ret;
int saved_errno;
- if (!obj) {
+ if (!obj)
+ {
_json_c_set_last_err("json_object_to_file: object is null\n");
return -1;
}
- if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
- _json_c_set_last_err("json_object_to_file: error opening file %s: %s\n",
- filename, strerror(errno));
+ if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0)
+ {
+ _json_c_set_last_err("json_object_to_file: error opening file %s: %s\n", filename,
+ strerror(errno));
return -1;
}
ret = _json_object_to_fd(fd, obj, flags, filename);
@@ -146,7 +175,8 @@
int json_object_to_fd(int fd, struct json_object *obj, int flags)
{
- if (!obj) {
+ if (!obj)
+ {
_json_c_set_last_err("json_object_to_fd: object is null\n");
return -1;
}
@@ -161,17 +191,21 @@
filename = filename ? filename : "(fd)";
- if (!(json_str = json_object_to_json_string_ext(obj,flags))) {
+ if (!(json_str = json_object_to_json_string_ext(obj, flags)))
+ {
return -1;
}
- wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
+ /* CAW: probably unnecessary, but the most 64bit safe */
+ wsize = (unsigned int)(strlen(json_str) & UINT_MAX);
wpos = 0;
- while(wpos < wsize) {
- if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
- _json_c_set_last_err("json_object_to_file: error writing file %s: %s\n",
- filename, strerror(errno));
- return -1;
+ while (wpos < wsize)
+ {
+ if ((ret = write(fd, json_str + wpos, wsize - wpos)) < 0)
+ {
+ _json_c_set_last_err("json_object_to_file: error writing file %s: %s\n",
+ filename, strerror(errno));
+ return -1;
}
/* because of the above check for ret < 0, we can safely cast and add */
@@ -185,14 +219,15 @@
int json_object_to_file(const char *filename, struct json_object *obj)
{
- return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN);
+ return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN);
}
+// Deprecated json_parse_double function. See json_tokener_parse_double instead.
int json_parse_double(const char *buf, double *retval)
{
- char *end;
- *retval = strtod(buf, &end);
- return end == buf ? 1 : 0;
+ char *end;
+ *retval = strtod(buf, &end);
+ return end == buf ? 1 : 0;
}
int json_parse_int64(const char *buf, int64_t *retval)
@@ -207,8 +242,25 @@
return ((val == 0 && errno != 0) || (end == buf)) ? 1 : 0;
}
+int json_parse_uint64(const char *buf, uint64_t *retval)
+{
+ char *end = NULL;
+ uint64_t val;
+
+ errno = 0;
+ while (*buf == ' ')
+ buf++;
+ if (*buf == '-')
+ return 1; /* error: uint cannot be negative */
+
+ val = strtoull(buf, &end, 10);
+ if (end != buf)
+ *retval = val;
+ return ((val == 0 && errno != 0) || (end == buf)) ? 1 : 0;
+}
+
#ifndef HAVE_REALLOC
-void* rpl_realloc(void* p, size_t n)
+void *rpl_realloc(void *p, size_t n)
{
if (n == 0)
n = 1;
@@ -218,26 +270,28 @@
}
#endif
-#define NELEM(a) (sizeof(a) / sizeof(a[0]))
-static const char* json_type_name[] = {
- /* If you change this, be sure to update the enum json_type definition too */
- "null",
- "boolean",
- "double",
- "int",
- "object",
- "array",
- "string",
+#define NELEM(a) (sizeof(a) / sizeof(a[0]))
+/* clang-format off */
+static const char *json_type_name[] = {
+ /* If you change this, be sure to update the enum json_type definition too */
+ "null",
+ "boolean",
+ "double",
+ "int",
+ "object",
+ "array",
+ "string",
};
+/* clang-format on */
const char *json_type_to_name(enum json_type o_type)
{
int o_type_int = (int)o_type;
if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name))
{
- _json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type, NELEM(json_type_name));
+ _json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type,
+ NELEM(json_type_name));
return NULL;
}
return json_type_name[o_type];
}
-
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_util.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_util.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_util.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_util.h 2022-04-15 07:49:21.000000000 +0000
@@ -12,21 +12,20 @@
/**
* @file
* @brief Miscllaneous utility functions and macros.
- */
+ */
#ifndef _json_util_h_
#define _json_util_h_
#include "json_object.h"
#ifndef json_min
-#define json_min(a,b) ((a) < (b) ? (a) : (b))
+#define json_min(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef json_max
-#define json_max(a,b) ((a) > (b) ? (a) : (b))
+#define json_max(a, b) ((a) > (b) ? (a) : (b))
#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -38,9 +37,9 @@
* Read the full contents of the given file, then convert it to a
* json_object using json_tokener_parse().
*
- * Returns -1 if something fails. See json_util_get_last_err() for details.
+ * Returns NULL on failure. See json_util_get_last_err() for details.
*/
-extern struct json_object* json_object_from_file(const char *filename);
+JSON_EXPORT struct json_object *json_object_from_file(const char *filename);
/**
* Create a JSON object from already opened file descriptor.
@@ -50,9 +49,21 @@
* Note, that the fd must be readable at the actual position, i.e.
* use lseek(fd, 0, SEEK_SET) before.
*
- * Returns -1 if something fails. See json_util_get_last_err() for details.
+ * The depth argument specifies the maximum object depth to pass to
+ * json_tokener_new_ex(). When depth == -1, JSON_TOKENER_DEFAULT_DEPTH
+ * is used instead.
+ *
+ * Returns NULL on failure. See json_util_get_last_err() for details.
+ */
+JSON_EXPORT struct json_object *json_object_from_fd_ex(int fd, int depth);
+
+/**
+ * Create a JSON object from an already opened file descriptor, using
+ * the default maximum object depth. (JSON_TOKENER_DEFAULT_DEPTH)
+ *
+ * See json_object_from_fd_ex() for details.
*/
-extern struct json_object* json_object_from_fd(int fd);
+JSON_EXPORT struct json_object *json_object_from_fd(int fd);
/**
* Equivalent to:
@@ -60,7 +71,7 @@
*
* Returns -1 if something fails. See json_util_get_last_err() for details.
*/
-extern int json_object_to_file(const char *filename, struct json_object *obj);
+JSON_EXPORT int json_object_to_file(const char *filename, struct json_object *obj);
/**
* Open and truncate the given file, creating it if necessary, then
@@ -68,7 +79,7 @@
*
* Returns -1 if something fails. See json_util_get_last_err() for details.
*/
-extern int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags);
+JSON_EXPORT int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags);
/**
* Convert the json_object to a string and write it to the file descriptor.
@@ -80,24 +91,28 @@
* @param flags flags to pass to json_object_to_json_string_ext()
* @return -1 if something fails. See json_util_get_last_err() for details.
*/
-extern int json_object_to_fd(int fd, struct json_object *obj, int flags);
+JSON_EXPORT int json_object_to_fd(int fd, struct json_object *obj, int flags);
/**
* Return the last error from various json-c functions, including:
* json_object_to_file{,_ext}, json_object_to_fd() or
* json_object_from_{file,fd}, or NULL if there is none.
*/
-const char *json_util_get_last_err(void);
+JSON_EXPORT const char *json_util_get_last_err(void);
-
-extern int json_parse_int64(const char *buf, int64_t *retval);
-extern int json_parse_double(const char *buf, double *retval);
+/* these parsing helpers return zero on success */
+JSON_EXPORT int json_parse_int64(const char *buf, int64_t *retval);
+JSON_EXPORT int json_parse_uint64(const char *buf, uint64_t *retval);
+/**
+ * @deprecated
+ */
+JSON_EXPORT int json_parse_double(const char *buf, double *retval);
/**
* Return a string describing the type of the object.
* e.g. "int", or "object", etc...
*/
-extern const char *json_type_to_name(enum json_type o_type);
+JSON_EXPORT const char *json_type_to_name(enum json_type o_type);
#ifdef __cplusplus
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_visit.c thunderbird-91.8.1+build1/comm/third_party/json-c/json_visit.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_visit.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_visit.c 2022-04-15 07:49:22.000000000 +0000
@@ -13,45 +13,39 @@
#include "json_visit.h"
#include "linkhash.h"
-static int _json_c_visit(json_object *jso, json_object *parent_jso,
- const char *jso_key, size_t *jso_index,
- json_c_visit_userfunc *userfunc, void *userarg);
+static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key,
+ size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg);
-int json_c_visit(json_object *jso, int future_flags,
- json_c_visit_userfunc *userfunc, void *userarg)
+int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc, void *userarg)
{
int ret = _json_c_visit(jso, NULL, NULL, NULL, userfunc, userarg);
- switch(ret)
+ switch (ret)
{
case JSON_C_VISIT_RETURN_CONTINUE:
case JSON_C_VISIT_RETURN_SKIP:
case JSON_C_VISIT_RETURN_POP:
- case JSON_C_VISIT_RETURN_STOP:
- return 0;
- default:
- return JSON_C_VISIT_RETURN_ERROR;
+ case JSON_C_VISIT_RETURN_STOP: return 0;
+ default: return JSON_C_VISIT_RETURN_ERROR;
}
}
-static int _json_c_visit(json_object *jso, json_object *parent_jso,
- const char *jso_key, size_t *jso_index,
- json_c_visit_userfunc *userfunc, void *userarg)
+static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key,
+ size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg)
{
int userret = userfunc(jso, 0, parent_jso, jso_key, jso_index, userarg);
- switch(userret)
+ switch (userret)
{
- case JSON_C_VISIT_RETURN_CONTINUE:
- break;
+ case JSON_C_VISIT_RETURN_CONTINUE: break;
case JSON_C_VISIT_RETURN_SKIP:
case JSON_C_VISIT_RETURN_POP:
case JSON_C_VISIT_RETURN_STOP:
- case JSON_C_VISIT_RETURN_ERROR:
- return userret;
+ case JSON_C_VISIT_RETURN_ERROR: return userret;
default:
- fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret);
+ fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n",
+ userret);
return JSON_C_VISIT_RETURN_ERROR;
}
- switch(json_object_get_type(jso))
+ switch (json_object_get_type(jso))
{
case json_type_null:
case json_type_boolean:
@@ -69,12 +63,13 @@
if (userret == JSON_C_VISIT_RETURN_POP)
break;
if (userret == JSON_C_VISIT_RETURN_STOP ||
- userret == JSON_C_VISIT_RETURN_ERROR)
+ userret == JSON_C_VISIT_RETURN_ERROR)
return userret;
if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
- userret != JSON_C_VISIT_RETURN_SKIP)
+ userret != JSON_C_VISIT_RETURN_SKIP)
{
- fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret);
+ fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n",
+ userret);
return JSON_C_VISIT_RETURN_ERROR;
}
}
@@ -91,19 +86,21 @@
if (userret == JSON_C_VISIT_RETURN_POP)
break;
if (userret == JSON_C_VISIT_RETURN_STOP ||
- userret == JSON_C_VISIT_RETURN_ERROR)
+ userret == JSON_C_VISIT_RETURN_ERROR)
return userret;
if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
- userret != JSON_C_VISIT_RETURN_SKIP)
+ userret != JSON_C_VISIT_RETURN_SKIP)
{
- fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret);
+ fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n",
+ userret);
return JSON_C_VISIT_RETURN_ERROR;
}
}
break;
}
default:
- fprintf(stderr, "INTERNAL ERROR: _json_c_visit found object of unknown type: %d\n", json_object_get_type(jso));
+ fprintf(stderr, "INTERNAL ERROR: _json_c_visit found object of unknown type: %d\n",
+ json_object_get_type(jso));
return JSON_C_VISIT_RETURN_ERROR;
}
@@ -112,22 +109,20 @@
// Non-container types will have already returned before this point.
userret = userfunc(jso, JSON_C_VISIT_SECOND, parent_jso, jso_key, jso_index, userarg);
- switch(userret)
+ switch (userret)
{
case JSON_C_VISIT_RETURN_SKIP:
case JSON_C_VISIT_RETURN_POP:
- // These are not really sensible during JSON_C_VISIT_SECOND,
+ // These are not really sensible during JSON_C_VISIT_SECOND,
// but map them to JSON_C_VISIT_CONTINUE anyway.
// FALLTHROUGH
- case JSON_C_VISIT_RETURN_CONTINUE:
- return JSON_C_VISIT_RETURN_CONTINUE;
+ case JSON_C_VISIT_RETURN_CONTINUE: return JSON_C_VISIT_RETURN_CONTINUE;
case JSON_C_VISIT_RETURN_STOP:
- case JSON_C_VISIT_RETURN_ERROR:
- return userret;
+ case JSON_C_VISIT_RETURN_ERROR: return userret;
default:
- fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret);
+ fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n",
+ userret);
return JSON_C_VISIT_RETURN_ERROR;
}
// NOTREACHED
}
-
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/json_visit.h thunderbird-91.8.1+build1/comm/third_party/json-c/json_visit.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/json_visit.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/json_visit.h 2022-04-15 07:49:21.000000000 +0000
@@ -8,9 +8,12 @@
*/
#include "json_object.h"
-typedef int (json_c_visit_userfunc)(json_object *jso, int flags,
- json_object *parent_jso, const char *jso_key,
- size_t *jso_index, void *userarg);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int(json_c_visit_userfunc)(json_object *jso, int flags, json_object *parent_jso,
+ const char *jso_key, size_t *jso_index, void *userarg);
/**
* Visit each object in the JSON hierarchy starting at jso.
@@ -26,20 +29,20 @@
* userfunc must return one of the defined return values, to indicate
* whether and how to continue visiting nodes, or one of various ways to stop.
*
- * Returns 0 if nodes were visited successfully, even if some were
+ * Returns 0 if nodes were visited successfully, even if some were
* intentionally skipped due to what userfunc returned.
* Returns <0 if an error occurred during iteration, including if
* userfunc returned JSON_C_VISIT_RETURN_ERROR.
*/
-int json_c_visit(json_object *jso, int future_flags,
- json_c_visit_userfunc *userfunc, void *userarg);
+JSON_EXPORT int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc,
+ void *userarg);
/**
* Passed to json_c_visit_userfunc as one of the flags values to indicate
* that this is the second time a container (array or object) is being
* called, after all of it's members have been iterated over.
*/
-#define JSON_C_VISIT_SECOND 0x02
+#define JSON_C_VISIT_SECOND 0x02
/**
* This json_c_visit_userfunc return value indicates that iteration
@@ -47,7 +50,6 @@
*/
#define JSON_C_VISIT_RETURN_CONTINUE 0
-
/**
* This json_c_visit_userfunc return value indicates that iteration
* over the members of the current object should be skipped.
@@ -60,7 +62,7 @@
* This json_c_visit_userfunc return value indicates that iteration
* of the fields/elements of the containing object should stop
* and continue "popped up" a level of the object hierarchy.
- * For example, returning this when handling arg will result in
+ * For example, returning this when handling arg will result in
* arg3 and any other fields being skipped. The next call to userfunc
* will be the JSON_C_VISIT_SECOND call on "foo", followed by a userfunc
* call on "bar".
@@ -92,4 +94,8 @@
*/
#define JSON_C_VISIT_RETURN_ERROR -1
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _json_c_json_visit_h_ */
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/libjson.c thunderbird-91.8.1+build1/comm/third_party/json-c/libjson.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/libjson.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/libjson.c 2022-04-15 07:49:21.000000000 +0000
@@ -7,13 +7,13 @@
#ifndef __warn_references
-#if defined(__GNUC__) && defined (HAS_GNU_WARNING_LONG)
+#if defined(__GNUC__) && defined(HAS_GNU_WARNING_LONG)
-#define __warn_references(sym,msg) \
- __asm__(".section .gnu" #sym ",\n\t.ascii \"" msg "\"\n\t.text");
+#define __warn_references(sym, msg) \
+ __asm__(".section .gnu" #sym ",\n\t.ascii \"" msg "\"\n\t.text");
#else
-#define __warn_references(sym,msg) /* nothing */
+#define __warn_references(sym, msg) /* nothing */
#endif
#endif
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/linkhash.c thunderbird-91.8.1+build1/comm/third_party/json-c/linkhash.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/linkhash.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/linkhash.c 2022-04-15 07:49:21.000000000 +0000
@@ -12,55 +12,46 @@
#include "config.h"
-#include
-#include
-#include
+#include
+#include
#include
#include
-#include
+#include
+#include
+#include
#ifdef HAVE_ENDIAN_H
-# include /* attempt to define endianness */
+#include /* attempt to define endianness */
#endif
#if defined(_MSC_VER) || defined(__MINGW32__)
-# define WIN32_LEAN_AND_MEAN
-# include /* Get InterlockedCompareExchange */
+#define WIN32_LEAN_AND_MEAN
+#include /* Get InterlockedCompareExchange */
#endif
-#include "random_seed.h"
#include "linkhash.h"
+#include "random_seed.h"
/* hash functions */
static unsigned long lh_char_hash(const void *k);
static unsigned long lh_perllike_str_hash(const void *k);
static lh_hash_fn *char_hash_fn = lh_char_hash;
-int
-json_global_set_string_hash(const int h)
+/* comparison functions */
+int lh_char_equal(const void *k1, const void *k2);
+int lh_ptr_equal(const void *k1, const void *k2);
+
+int json_global_set_string_hash(const int h)
{
- switch(h) {
- case JSON_C_STR_HASH_DFLT:
- char_hash_fn = lh_char_hash;
- break;
- case JSON_C_STR_HASH_PERLLIKE:
- char_hash_fn = lh_perllike_str_hash;
- break;
- default:
- return -1;
+ switch (h)
+ {
+ case JSON_C_STR_HASH_DFLT: char_hash_fn = lh_char_hash; break;
+ case JSON_C_STR_HASH_PERLLIKE: char_hash_fn = lh_perllike_str_hash; break;
+ default: return -1;
}
return 0;
}
-void lh_abort(const char *msg, ...)
-{
- va_list ap;
- va_start(ap, msg);
- vprintf(msg, ap);
- va_end(ap);
- exit(1);
-}
-
static unsigned long lh_ptr_hash(const void *k)
{
/* CAW: refactored to be 64bit nice */
@@ -119,25 +110,23 @@
* My best guess at if you are big-endian or little-endian. This may
* need adjustment.
*/
-#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
- __BYTE_ORDER == __LITTLE_ENDIAN) || \
- (defined(i386) || defined(__i386__) || defined(__i486__) || \
- defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
-# define HASH_LITTLE_ENDIAN 1
-# define HASH_BIG_ENDIAN 0
-#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
- __BYTE_ORDER == __BIG_ENDIAN) || \
- (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
-# define HASH_LITTLE_ENDIAN 0
-# define HASH_BIG_ENDIAN 1
+#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \
+ (defined(i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || \
+ defined(__i686__) || defined(vax) || defined(MIPSEL))
+#define HASH_LITTLE_ENDIAN 1
+#define HASH_BIG_ENDIAN 0
+#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \
+ (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
+#define HASH_LITTLE_ENDIAN 0
+#define HASH_BIG_ENDIAN 1
#else
-# define HASH_LITTLE_ENDIAN 0
-# define HASH_BIG_ENDIAN 0
+#define HASH_LITTLE_ENDIAN 0
+#define HASH_BIG_ENDIAN 0
#endif
-#define hashsize(n) ((uint32_t)1<<(n))
-#define hashmask(n) (hashsize(n)-1)
-#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+#define hashsize(n) ((uint32_t)1 << (n))
+#define hashmask(n) (hashsize(n) - 1)
+#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
/*
-------------------------------------------------------------------------------
@@ -183,15 +172,17 @@
rotates.
-------------------------------------------------------------------------------
*/
+/* clang-format off */
#define mix(a,b,c) \
{ \
- a -= c; a ^= rot(c, 4); c += b; \
- b -= a; b ^= rot(a, 6); a += c; \
- c -= b; c ^= rot(b, 8); b += a; \
- a -= c; a ^= rot(c,16); c += b; \
- b -= a; b ^= rot(a,19); a += c; \
- c -= b; c ^= rot(b, 4); b += a; \
+ a -= c; a ^= rot(c, 4); c += b; \
+ b -= a; b ^= rot(a, 6); a += c; \
+ c -= b; c ^= rot(b, 8); b += a; \
+ a -= c; a ^= rot(c,16); c += b; \
+ b -= a; b ^= rot(a,19); a += c; \
+ c -= b; c ^= rot(b, 4); b += a; \
}
+/* clang-format on */
/*
-------------------------------------------------------------------------------
@@ -218,17 +209,18 @@
11 8 15 26 3 22 24
-------------------------------------------------------------------------------
*/
+/* clang-format off */
#define final(a,b,c) \
{ \
- c ^= b; c -= rot(b,14); \
- a ^= c; a -= rot(c,11); \
- b ^= a; b -= rot(a,25); \
- c ^= b; c -= rot(b,16); \
- a ^= c; a -= rot(c,4); \
- b ^= a; b -= rot(a,14); \
- c ^= b; c -= rot(b,24); \
+ c ^= b; c -= rot(b,14); \
+ a ^= c; a -= rot(c,11); \
+ b ^= a; b -= rot(a,25); \
+ c ^= b; c -= rot(b,16); \
+ a ^= c; a -= rot(c,4); \
+ b ^= a; b -= rot(a,14); \
+ c ^= b; c -= rot(b,24); \
}
-
+/* clang-format on */
/*
-------------------------------------------------------------------------------
@@ -257,197 +249,208 @@
-------------------------------------------------------------------------------
*/
-static uint32_t hashlittle( const void *key, size_t length, uint32_t initval)
+/* clang-format off */
+static uint32_t hashlittle(const void *key, size_t length, uint32_t initval)
{
- uint32_t a,b,c; /* internal state */
- union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */
+ uint32_t a,b,c; /* internal state */
+ union
+ {
+ const void *ptr;
+ size_t i;
+ } u; /* needed for Mac Powerbook G4 */
+
+ /* Set up the internal state */
+ a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
+
+ u.ptr = key;
+ if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
+ const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
- /* Set up the internal state */
- a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
+ /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ mix(a,b,c);
+ length -= 12;
+ k += 3;
+ }
- u.ptr = key;
- if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
- const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
-
- /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
- while (length > 12)
- {
- a += k[0];
- b += k[1];
- c += k[2];
- mix(a,b,c);
- length -= 12;
- k += 3;
- }
-
- /*----------------------------- handle the last (probably partial) block */
- /*
- * "k[2]&0xffffff" actually reads beyond the end of the string, but
- * then masks off the part it's not allowed to read. Because the
- * string is aligned, the masked-off tail is in the same word as the
- * rest of the string. Every machine with memory protection I've seen
- * does it on word boundaries, so is OK with this. But VALGRIND will
- * still catch it and complain. The masking trick does make the hash
- * noticably faster for short strings (like English words).
- * AddressSanitizer is similarly picky about overrunning
- * the buffer. (http://clang.llvm.org/docs/AddressSanitizer.html
- */
+ /*----------------------------- handle the last (probably partial) block */
+ /*
+ * "k[2]&0xffffff" actually reads beyond the end of the string, but
+ * then masks off the part it's not allowed to read. Because the
+ * string is aligned, the masked-off tail is in the same word as the
+ * rest of the string. Every machine with memory protection I've seen
+ * does it on word boundaries, so is OK with this. But VALGRIND will
+ * still catch it and complain. The masking trick does make the hash
+ * noticably faster for short strings (like English words).
+ * AddressSanitizer is similarly picky about overrunning
+ * the buffer. (http://clang.llvm.org/docs/AddressSanitizer.html
+ */
#ifdef VALGRIND
-# define PRECISE_MEMORY_ACCESS 1
+#define PRECISE_MEMORY_ACCESS 1
#elif defined(__SANITIZE_ADDRESS__) /* GCC's ASAN */
-# define PRECISE_MEMORY_ACCESS 1
+#define PRECISE_MEMORY_ACCESS 1
#elif defined(__has_feature)
-# if __has_feature(address_sanitizer) /* Clang's ASAN */
-# define PRECISE_MEMORY_ACCESS 1
-# endif
+#if __has_feature(address_sanitizer) /* Clang's ASAN */
+#define PRECISE_MEMORY_ACCESS 1
+#endif
#endif
#ifndef PRECISE_MEMORY_ACCESS
- switch(length)
- {
- case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
- case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
- case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
- case 8 : b+=k[1]; a+=k[0]; break;
- case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
- case 6 : b+=k[1]&0xffff; a+=k[0]; break;
- case 5 : b+=k[1]&0xff; a+=k[0]; break;
- case 4 : a+=k[0]; break;
- case 3 : a+=k[0]&0xffffff; break;
- case 2 : a+=k[0]&0xffff; break;
- case 1 : a+=k[0]&0xff; break;
- case 0 : return c; /* zero length strings require no mixing */
- }
+ switch(length)
+ {
+ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+ case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
+ case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
+ case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
+ case 8 : b+=k[1]; a+=k[0]; break;
+ case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
+ case 6 : b+=k[1]&0xffff; a+=k[0]; break;
+ case 5 : b+=k[1]&0xff; a+=k[0]; break;
+ case 4 : a+=k[0]; break;
+ case 3 : a+=k[0]&0xffffff; break;
+ case 2 : a+=k[0]&0xffff; break;
+ case 1 : a+=k[0]&0xff; break;
+ case 0 : return c; /* zero length strings require no mixing */
+ }
#else /* make valgrind happy */
- const uint8_t *k8 = (const uint8_t *)k;
- switch(length)
- {
- case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
- case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
- case 9 : c+=k8[8]; /* fall through */
- case 8 : b+=k[1]; a+=k[0]; break;
- case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
- case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
- case 5 : b+=k8[4]; /* fall through */
- case 4 : a+=k[0]; break;
- case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
- case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
- case 1 : a+=k8[0]; break;
- case 0 : return c;
- }
+ const uint8_t *k8 = (const uint8_t *)k;
+ switch(length)
+ {
+ case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
+ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
+ case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
+ case 9 : c+=k8[8]; /* fall through */
+ case 8 : b+=k[1]; a+=k[0]; break;
+ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
+ case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
+ case 5 : b+=k8[4]; /* fall through */
+ case 4 : a+=k[0]; break;
+ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
+ case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
+ case 1 : a+=k8[0]; break;
+ case 0 : return c;
+ }
#endif /* !valgrind */
- } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
- const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
- const uint8_t *k8;
-
- /*--------------- all but last block: aligned reads and different mixing */
- while (length > 12)
- {
- a += k[0] + (((uint32_t)k[1])<<16);
- b += k[2] + (((uint32_t)k[3])<<16);
- c += k[4] + (((uint32_t)k[5])<<16);
- mix(a,b,c);
- length -= 12;
- k += 6;
- }
-
- /*----------------------------- handle the last (probably partial) block */
- k8 = (const uint8_t *)k;
- switch(length)
- {
- case 12: c+=k[4]+(((uint32_t)k[5])<<16);
- b+=k[2]+(((uint32_t)k[3])<<16);
- a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
- case 10: c+=k[4];
- b+=k[2]+(((uint32_t)k[3])<<16);
- a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 9 : c+=k8[8]; /* fall through */
- case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
- a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
- case 6 : b+=k[2];
- a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 5 : b+=k8[4]; /* fall through */
- case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
- case 2 : a+=k[0];
- break;
- case 1 : a+=k8[0];
- break;
- case 0 : return c; /* zero length requires no mixing */
- }
-
- } else { /* need to read the key one byte at a time */
- const uint8_t *k = (const uint8_t *)key;
-
- /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
- while (length > 12)
- {
- a += k[0];
- a += ((uint32_t)k[1])<<8;
- a += ((uint32_t)k[2])<<16;
- a += ((uint32_t)k[3])<<24;
- b += k[4];
- b += ((uint32_t)k[5])<<8;
- b += ((uint32_t)k[6])<<16;
- b += ((uint32_t)k[7])<<24;
- c += k[8];
- c += ((uint32_t)k[9])<<8;
- c += ((uint32_t)k[10])<<16;
- c += ((uint32_t)k[11])<<24;
- mix(a,b,c);
- length -= 12;
- k += 12;
- }
-
- /*-------------------------------- last block: affect all 32 bits of (c) */
- switch(length) /* all the case statements fall through */
- {
- case 12: c+=((uint32_t)k[11])<<24; /* FALLTHRU */
- case 11: c+=((uint32_t)k[10])<<16; /* FALLTHRU */
- case 10: c+=((uint32_t)k[9])<<8; /* FALLTHRU */
- case 9 : c+=k[8]; /* FALLTHRU */
- case 8 : b+=((uint32_t)k[7])<<24; /* FALLTHRU */
- case 7 : b+=((uint32_t)k[6])<<16; /* FALLTHRU */
- case 6 : b+=((uint32_t)k[5])<<8; /* FALLTHRU */
- case 5 : b+=k[4]; /* FALLTHRU */
- case 4 : a+=((uint32_t)k[3])<<24; /* FALLTHRU */
- case 3 : a+=((uint32_t)k[2])<<16; /* FALLTHRU */
- case 2 : a+=((uint32_t)k[1])<<8; /* FALLTHRU */
- case 1 : a+=k[0];
- break;
- case 0 : return c;
- }
- }
+ }
+ else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0))
+ {
+ const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
+ const uint8_t *k8;
+
+ /*--------------- all but last block: aligned reads and different mixing */
+ while (length > 12)
+ {
+ a += k[0] + (((uint32_t)k[1])<<16);
+ b += k[2] + (((uint32_t)k[3])<<16);
+ c += k[4] + (((uint32_t)k[5])<<16);
+ mix(a,b,c);
+ length -= 12;
+ k += 6;
+ }
- final(a,b,c);
- return c;
+ /*----------------------------- handle the last (probably partial) block */
+ k8 = (const uint8_t *)k;
+ switch(length)
+ {
+ case 12: c+=k[4]+(((uint32_t)k[5])<<16);
+ b+=k[2]+(((uint32_t)k[3])<<16);
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
+ case 10: c+=k[4];
+ b+=k[2]+(((uint32_t)k[3])<<16);
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 9 : c+=k8[8]; /* fall through */
+ case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
+ case 6 : b+=k[2];
+ a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 5 : b+=k8[4]; /* fall through */
+ case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
+ break;
+ case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
+ case 2 : a+=k[0];
+ break;
+ case 1 : a+=k8[0];
+ break;
+ case 0 : return c; /* zero length requires no mixing */
+ }
+
+ }
+ else
+ {
+ /* need to read the key one byte at a time */
+ const uint8_t *k = (const uint8_t *)key;
+
+ /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12)
+ {
+ a += k[0];
+ a += ((uint32_t)k[1])<<8;
+ a += ((uint32_t)k[2])<<16;
+ a += ((uint32_t)k[3])<<24;
+ b += k[4];
+ b += ((uint32_t)k[5])<<8;
+ b += ((uint32_t)k[6])<<16;
+ b += ((uint32_t)k[7])<<24;
+ c += k[8];
+ c += ((uint32_t)k[9])<<8;
+ c += ((uint32_t)k[10])<<16;
+ c += ((uint32_t)k[11])<<24;
+ mix(a,b,c);
+ length -= 12;
+ k += 12;
+ }
+
+ /*-------------------------------- last block: affect all 32 bits of (c) */
+ switch(length) /* all the case statements fall through */
+ {
+ case 12: c+=((uint32_t)k[11])<<24; /* FALLTHRU */
+ case 11: c+=((uint32_t)k[10])<<16; /* FALLTHRU */
+ case 10: c+=((uint32_t)k[9])<<8; /* FALLTHRU */
+ case 9 : c+=k[8]; /* FALLTHRU */
+ case 8 : b+=((uint32_t)k[7])<<24; /* FALLTHRU */
+ case 7 : b+=((uint32_t)k[6])<<16; /* FALLTHRU */
+ case 6 : b+=((uint32_t)k[5])<<8; /* FALLTHRU */
+ case 5 : b+=k[4]; /* FALLTHRU */
+ case 4 : a+=((uint32_t)k[3])<<24; /* FALLTHRU */
+ case 3 : a+=((uint32_t)k[2])<<16; /* FALLTHRU */
+ case 2 : a+=((uint32_t)k[1])<<8; /* FALLTHRU */
+ case 1 : a+=k[0];
+ break;
+ case 0 : return c;
+ }
+ }
+
+ final(a,b,c);
+ return c;
}
+/* clang-format on */
/* a simple hash function similiar to what perl does for strings.
* for good results, the string should not be excessivly large.
*/
-static unsigned long lh_perllike_str_hash(const void *k)
+static unsigned long lh_perllike_str_hash(const void *k)
{
- const char *rkey = (const char *)k;
- unsigned hashval = 1;
+ const char *rkey = (const char *)k;
+ unsigned hashval = 1;
- while (*rkey)
- hashval = hashval * 33 + *rkey++;
+ while (*rkey)
+ hashval = hashval * 33 + *rkey++;
- return hashval;
+ return hashval;
}
static unsigned long lh_char_hash(const void *k)
@@ -459,10 +462,11 @@
#endif
static volatile RANDOM_SEED_TYPE random_seed = -1;
- if (random_seed == -1) {
+ if (random_seed == -1)
+ {
RANDOM_SEED_TYPE seed;
/* we can't use -1 as it is the unitialized sentinel */
- while ((seed = json_c_get_random_seed()) == -1);
+ while ((seed = json_c_get_random_seed()) == -1) {}
#if SIZEOF_INT == 8 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
#define USE_SYNC_COMPARE_AND_SWAP 1
#endif
@@ -477,34 +481,34 @@
#elif defined _MSC_VER || defined __MINGW32__
InterlockedCompareExchange(&random_seed, seed, -1);
#else
-//#warning "racy random seed initializtion if used by multiple threads"
+ //#warning "racy random seed initializtion if used by multiple threads"
random_seed = seed; /* potentially racy */
#endif
}
- return hashlittle((const char*)k, strlen((const char*)k), random_seed);
+ return hashlittle((const char *)k, strlen((const char *)k), random_seed);
}
int lh_char_equal(const void *k1, const void *k2)
{
- return (strcmp((const char*)k1, (const char*)k2) == 0);
+ return (strcmp((const char *)k1, (const char *)k2) == 0);
}
-struct lh_table* lh_table_new(int size,
- lh_entry_free_fn *free_fn,
- lh_hash_fn *hash_fn,
- lh_equal_fn *equal_fn)
+struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn,
+ lh_equal_fn *equal_fn)
{
int i;
struct lh_table *t;
- t = (struct lh_table*)calloc(1, sizeof(struct lh_table));
+ /* Allocate space for elements to avoid divisions by zero. */
+ assert(size > 0);
+ t = (struct lh_table *)calloc(1, sizeof(struct lh_table));
if (!t)
return NULL;
t->count = 0;
t->size = size;
- t->table = (struct lh_entry*)calloc(size, sizeof(struct lh_entry));
+ t->table = (struct lh_entry *)calloc(size, sizeof(struct lh_entry));
if (!t->table)
{
free(t);
@@ -513,18 +517,17 @@
t->free_fn = free_fn;
t->hash_fn = hash_fn;
t->equal_fn = equal_fn;
- for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY;
+ for (i = 0; i < size; i++)
+ t->table[i].k = LH_EMPTY;
return t;
}
-struct lh_table* lh_kchar_table_new(int size,
- lh_entry_free_fn *free_fn)
+struct lh_table *lh_kchar_table_new(int size, lh_entry_free_fn *free_fn)
{
return lh_table_new(size, free_fn, char_hash_fn, lh_char_equal);
}
-struct lh_table* lh_kptr_table_new(int size,
- lh_entry_free_fn *free_fn)
+struct lh_table *lh_kptr_table_new(int size, lh_entry_free_fn *free_fn)
{
return lh_table_new(size, free_fn, lh_ptr_hash, lh_ptr_equal);
}
@@ -563,28 +566,36 @@
void lh_table_free(struct lh_table *t)
{
struct lh_entry *c;
- if(t->free_fn) {
- for(c = t->head; c != NULL; c = c->next)
+ if (t->free_fn)
+ {
+ for (c = t->head; c != NULL; c = c->next)
t->free_fn(c);
}
free(t->table);
free(t);
}
-
-int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts)
+int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h,
+ const unsigned opts)
{
unsigned long n;
if (t->count >= t->size * LH_LOAD_FACTOR)
- if (lh_table_resize(t, t->size * 2) != 0)
+ {
+ /* Avoid signed integer overflow with large tables. */
+ int new_size = (t->size > INT_MAX / 2) ? INT_MAX : (t->size * 2);
+ if (t->size == INT_MAX || lh_table_resize(t, new_size) != 0)
return -1;
+ }
n = h % t->size;
- while( 1 ) {
- if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break;
- if ((int)++n == t->size) n = 0;
+ while (1)
+ {
+ if (t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED)
+ break;
+ if ((int)++n == t->size)
+ n = 0;
}
t->table[n].k = k;
@@ -592,10 +603,13 @@
t->table[n].v = v;
t->count++;
- if(t->head == NULL) {
+ if (t->head == NULL)
+ {
t->head = t->tail = &t->table[n];
t->table[n].next = t->table[n].prev = NULL;
- } else {
+ }
+ else
+ {
t->tail->next = &t->table[n];
t->table[n].prev = t->tail;
t->table[n].next = NULL;
@@ -609,66 +623,78 @@
return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k), 0);
}
-
-struct lh_entry* lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, const unsigned long h)
+struct lh_entry *lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k,
+ const unsigned long h)
{
unsigned long n = h % t->size;
int count = 0;
- while( count < t->size ) {
- if(t->table[n].k == LH_EMPTY) return NULL;
- if(t->table[n].k != LH_FREED &&
- t->equal_fn(t->table[n].k, k)) return &t->table[n];
- if ((int)++n == t->size) n = 0;
+ while (count < t->size)
+ {
+ if (t->table[n].k == LH_EMPTY)
+ return NULL;
+ if (t->table[n].k != LH_FREED && t->equal_fn(t->table[n].k, k))
+ return &t->table[n];
+ if ((int)++n == t->size)
+ n = 0;
count++;
}
return NULL;
}
-struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
+struct lh_entry *lh_table_lookup_entry(struct lh_table *t, const void *k)
{
return lh_table_lookup_entry_w_hash(t, k, lh_get_hash(t, k));
}
-const void* lh_table_lookup(struct lh_table *t, const void *k)
-{
- void *result;
- lh_table_lookup_ex(t, k, &result);
- return result;
-}
-
-json_bool lh_table_lookup_ex(struct lh_table* t, const void* k, void **v)
+json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v)
{
struct lh_entry *e = lh_table_lookup_entry(t, k);
- if (e != NULL) {
- if (v != NULL) *v = lh_entry_v(e);
- return TRUE; /* key found */
+ if (e != NULL)
+ {
+ if (v != NULL)
+ *v = lh_entry_v(e);
+ return 1; /* key found */
}
- if (v != NULL) *v = NULL;
- return FALSE; /* key not found */
+ if (v != NULL)
+ *v = NULL;
+ return 0; /* key not found */
}
int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
{
- ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */
+ /* CAW: fixed to be 64bit nice, still need the crazy negative case... */
+ ptrdiff_t n = (ptrdiff_t)(e - t->table);
/* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */
- if(n < 0) { return -2; }
+ if (n < 0)
+ {
+ return -2;
+ }
- if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1;
+ if (t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED)
+ return -1;
t->count--;
- if(t->free_fn) t->free_fn(e);
+ if (t->free_fn)
+ t->free_fn(e);
t->table[n].v = NULL;
t->table[n].k = LH_FREED;
- if(t->tail == &t->table[n] && t->head == &t->table[n]) {
+ if (t->tail == &t->table[n] && t->head == &t->table[n])
+ {
t->head = t->tail = NULL;
- } else if (t->head == &t->table[n]) {
+ }
+ else if (t->head == &t->table[n])
+ {
t->head->next->prev = NULL;
t->head = t->head->next;
- } else if (t->tail == &t->table[n]) {
+ }
+ else if (t->tail == &t->table[n])
+ {
t->tail->prev->next = NULL;
t->tail = t->tail->prev;
- } else {
+ }
+ else
+ {
t->table[n].prev->next = t->table[n].next;
t->table[n].next->prev = t->table[n].prev;
}
@@ -676,11 +702,11 @@
return 0;
}
-
int lh_table_delete(struct lh_table *t, const void *k)
{
struct lh_entry *e = lh_table_lookup_entry(t, k);
- if(!e) return -1;
+ if (!e)
+ return -1;
return lh_table_delete_entry(t, e);
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/linkhash.h thunderbird-91.8.1+build1/comm/third_party/json-c/linkhash.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/linkhash.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/linkhash.h 2022-04-15 07:49:21.000000000 +0000
@@ -40,12 +40,12 @@
/**
* sentinel pointer value for empty slots
*/
-#define LH_EMPTY (void*)-1
+#define LH_EMPTY (void *)-1
/**
* sentinel pointer value for freed slots
*/
-#define LH_FREED (void*)-2
+#define LH_FREED (void *)-2
/**
* default string hash function
@@ -69,20 +69,21 @@
/**
* callback function prototypes
*/
-typedef void (lh_entry_free_fn) (struct lh_entry *e);
+typedef void(lh_entry_free_fn)(struct lh_entry *e);
/**
* callback function prototypes
*/
-typedef unsigned long (lh_hash_fn) (const void *k);
+typedef unsigned long(lh_hash_fn)(const void *k);
/**
* callback function prototypes
*/
-typedef int (lh_equal_fn) (const void *k1, const void *k2);
+typedef int(lh_equal_fn)(const void *k1, const void *k2);
/**
* An entry in the hash table
*/
-struct lh_entry {
+struct lh_entry
+{
/**
* The key. Use lh_entry_k() instead of accessing this directly.
*/
@@ -106,11 +107,11 @@
struct lh_entry *prev;
};
-
/**
* The hash table structure.
*/
-struct lh_table {
+struct lh_table
+{
/**
* Size of our hash.
*/
@@ -141,12 +142,10 @@
};
typedef struct lh_table lh_table;
-
/**
* Convenience list iterator.
*/
-#define lh_foreach(table, entry) \
-for(entry = table->head; entry; entry = entry->next)
+#define lh_foreach(table, entry) for (entry = table->head; entry; entry = entry->next)
/**
* lh_foreach_safe allows calling of deletion routine while iterating.
@@ -156,9 +155,7 @@
* @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element
*/
#define lh_foreach_safe(table, entry, tmp) \
-for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
-
-
+ for (entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
/**
* Create a new linkhash table.
@@ -178,10 +175,8 @@
* @return On success, a pointer to the new linkhash table is returned.
* On error, a null pointer is returned.
*/
-extern struct lh_table* lh_table_new(int size,
- lh_entry_free_fn *free_fn,
- lh_hash_fn *hash_fn,
- lh_equal_fn *equal_fn);
+extern struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn,
+ lh_equal_fn *equal_fn);
/**
* Convenience function to create a new linkhash table with char keys.
@@ -191,9 +186,7 @@
* @return On success, a pointer to the new linkhash table is returned.
* On error, a null pointer is returned.
*/
-extern struct lh_table* lh_kchar_table_new(int size,
- lh_entry_free_fn *free_fn);
-
+extern struct lh_table *lh_kchar_table_new(int size, lh_entry_free_fn *free_fn);
/**
* Convenience function to create a new linkhash table with ptr keys.
@@ -203,9 +196,7 @@
* @return On success, a pointer to the new linkhash table is returned.
* On error, a null pointer is returned.
*/
-extern struct lh_table* lh_kptr_table_new(int size,
- lh_entry_free_fn *free_fn);
-
+extern struct lh_table *lh_kptr_table_new(int size, lh_entry_free_fn *free_fn);
/**
* Free a linkhash table.
@@ -217,7 +208,6 @@
*/
extern void lh_table_free(struct lh_table *t);
-
/**
* Insert a record into the table.
*
@@ -230,7 +220,6 @@
*/
extern int lh_table_insert(struct lh_table *t, const void *k, const void *v);
-
/**
* Insert a record into the table using a precalculated key hash.
*
@@ -245,8 +234,8 @@
* @param opts if set to JSON_C_OBJECT_KEY_IS_CONSTANT, sets lh_entry.k_is_constant
* so t's free function knows to avoid freeing the key.
*/
-extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts);
-
+extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v,
+ const unsigned long h, const unsigned opts);
/**
* Lookup a record in the table.
@@ -255,7 +244,7 @@
* @param k a pointer to the key to lookup
* @return a pointer to the record structure of the value or NULL if it does not exist.
*/
-extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k);
+extern struct lh_entry *lh_table_lookup_entry(struct lh_table *t, const void *k);
/**
* Lookup a record in the table using a precalculated key hash.
@@ -269,17 +258,8 @@
* @param h hash value of the key to lookup
* @return a pointer to the record structure of the value or NULL if it does not exist.
*/
-extern struct lh_entry* lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, const unsigned long h);
-
-/**
- * Lookup a record into the table.
- *
- * @param t the table to lookup
- * @param k a pointer to the key to lookup
- * @return a pointer to the found value or NULL if it does not exist.
- * @deprecated Use lh_table_lookup_ex() instead.
- */
-THIS_FUNCTION_IS_DEPRECATED(extern const void* lh_table_lookup(struct lh_table *t, const void *k));
+extern struct lh_entry *lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k,
+ const unsigned long h);
/**
* Lookup a record in the table.
@@ -303,7 +283,6 @@
*/
extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
-
/**
* Delete a record from the table.
*
@@ -319,21 +298,6 @@
extern int lh_table_length(struct lh_table *t);
/**
- * Prints a message to stdout,
- * then exits the program with an exit code of 1.
- *
- * @param msg Message format string, like for printf.
- * @param ... Format args.
- *
- * @deprecated Since it is not a good idea to exit the entire program
- * because of an internal library failure, json-c will no longer
- * use this function internally.
- * However, because its interface is public, it will remain part of
- * the API on the off chance of legacy software using it externally.
- */
-THIS_FUNCTION_IS_DEPRECATED(void lh_abort(const char *msg, ...));
-
-/**
* Resizes the specified table.
*
* @param t Pointer to table to resize.
@@ -344,15 +308,14 @@
*/
int lh_table_resize(struct lh_table *t, int new_size);
-
/**
* @deprecated Don't use this outside of linkhash.h:
*/
-#if !defined(_MSC_VER) || (_MSC_VER > 1800)
+#if (defined(AIX_CC) || (defined(_MSC_VER) && (_MSC_VER <= 1800)) )
/* VS2010 can't handle inline funcs, so skip it there */
-#define _LH_INLINE inline
-#else
#define _LH_INLINE
+#else
+#define _LH_INLINE inline
#endif
/**
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/math_compat.h thunderbird-91.8.1+build1/comm/third_party/json-c/math_compat.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/math_compat.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/math_compat.h 2022-04-15 07:49:21.000000000 +0000
@@ -9,17 +9,24 @@
/* Define isnan, isinf, infinity and nan on Windows/MSVC */
#ifndef HAVE_DECL_ISNAN
-# ifdef HAVE_DECL__ISNAN
+#ifdef HAVE_DECL__ISNAN
#include
#define isnan(x) _isnan(x)
-# endif
+#else
+/* On platforms like AIX and "IBM i" we need to provide our own isnan */
+#define isnan(x) ((x) != (x))
+#endif
#endif
#ifndef HAVE_DECL_ISINF
-# ifdef HAVE_DECL__FINITE
+#ifdef HAVE_DECL__FINITE
#include
#define isinf(x) (!_finite(x))
-# endif
+#else
+#include
+/* On platforms like AIX and "IBM i" we need to provide our own isinf */
+#define isinf(x) ((x) < -DBL_MAX || (x) > DBL_MAX)
+#endif
#endif
#ifndef HAVE_DECL_INFINITY
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/printbuf.c thunderbird-91.8.1+build1/comm/third_party/json-c/printbuf.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/printbuf.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/printbuf.c 2022-04-15 07:49:21.000000000 +0000
@@ -15,14 +15,15 @@
#include "config.h"
+#include
#include
#include
#include
#ifdef HAVE_STDARG_H
-# include
+#include
#else /* !HAVE_STDARG_H */
-# error Not enough var arg support!
+#error Not enough var arg support!
#endif /* HAVE_STDARG_H */
#include "debug.h"
@@ -32,23 +33,24 @@
static int printbuf_extend(struct printbuf *p, int min_size);
-struct printbuf* printbuf_new(void)
+struct printbuf *printbuf_new(void)
{
- struct printbuf *p;
+ struct printbuf *p;
- p = (struct printbuf*)calloc(1, sizeof(struct printbuf));
- if(!p) return NULL;
- p->size = 32;
- p->bpos = 0;
- if(!(p->buf = (char*)malloc(p->size))) {
- free(p);
- return NULL;
- }
- p->buf[0]= '\0';
- return p;
+ p = (struct printbuf *)calloc(1, sizeof(struct printbuf));
+ if (!p)
+ return NULL;
+ p->size = 32;
+ p->bpos = 0;
+ if (!(p->buf = (char *)malloc(p->size)))
+ {
+ free(p);
+ return NULL;
+ }
+ p->buf[0] = '\0';
+ return p;
}
-
/**
* Extend the buffer p so it has a size of at least min_size.
*
@@ -64,16 +66,22 @@
if (p->size >= min_size)
return 0;
-
- new_size = p->size * 2;
- if (new_size < min_size + 8)
- new_size = min_size + 8;
+ /* Prevent signed integer overflows with large buffers. */
+ if (min_size > INT_MAX - 8)
+ return -1;
+ if (p->size > INT_MAX / 2)
+ new_size = min_size + 8;
+ else {
+ new_size = p->size * 2;
+ if (new_size < min_size + 8)
+ new_size = min_size + 8;
+ }
#ifdef PRINTBUF_DEBUG
MC_DEBUG("printbuf_memappend: realloc "
- "bpos=%d min_size=%d old_size=%d new_size=%d\n",
- p->bpos, min_size, p->size, new_size);
+ "bpos=%d min_size=%d old_size=%d new_size=%d\n",
+ p->bpos, min_size, p->size, new_size);
#endif /* PRINTBUF_DEBUG */
- if(!(t = (char*)realloc(p->buf, new_size)))
+ if (!(t = (char *)realloc(p->buf, new_size)))
return -1;
p->size = new_size;
p->buf = t;
@@ -82,14 +90,18 @@
int printbuf_memappend(struct printbuf *p, const char *buf, int size)
{
- if (p->size <= p->bpos + size + 1) {
- if (printbuf_extend(p, p->bpos + size + 1) < 0)
- return -1;
- }
- memcpy(p->buf + p->bpos, buf, size);
- p->bpos += size;
- p->buf[p->bpos]= '\0';
- return size;
+ /* Prevent signed integer overflows with large buffers. */
+ if (size > INT_MAX - p->bpos - 1)
+ return -1;
+ if (p->size <= p->bpos + size + 1)
+ {
+ if (printbuf_extend(p, p->bpos + size + 1) < 0)
+ return -1;
+ }
+ memcpy(p->buf + p->bpos, buf, size);
+ p->bpos += size;
+ p->buf[p->bpos] = '\0';
+ return size;
}
int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
@@ -98,6 +110,9 @@
if (offset == -1)
offset = pb->bpos;
+ /* Prevent signed integer overflows with large buffers. */
+ if (len > INT_MAX - offset)
+ return -1;
size_needed = offset + len;
if (pb->size < size_needed)
{
@@ -114,42 +129,51 @@
int sprintbuf(struct printbuf *p, const char *msg, ...)
{
- va_list ap;
- char *t;
- int size;
- char buf[128];
-
- /* user stack buffer first */
- va_start(ap, msg);
- size = vsnprintf(buf, 128, msg, ap);
- va_end(ap);
- /* if string is greater than stack buffer, then use dynamic string
- with vasprintf. Note: some implementation of vsnprintf return -1
- if output is truncated whereas some return the number of bytes that
- would have been written - this code handles both cases. */
- if(size == -1 || size > 127) {
- va_start(ap, msg);
- if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
- va_end(ap);
- printbuf_memappend(p, t, size);
- free(t);
- return size;
- } else {
- printbuf_memappend(p, buf, size);
- return size;
- }
+ va_list ap;
+ char *t;
+ int size;
+ char buf[128];
+
+ /* user stack buffer first */
+ va_start(ap, msg);
+ size = vsnprintf(buf, 128, msg, ap);
+ va_end(ap);
+ /* if string is greater than stack buffer, then use dynamic string
+ * with vasprintf. Note: some implementation of vsnprintf return -1
+ * if output is truncated whereas some return the number of bytes that
+ * would have been written - this code handles both cases.
+ */
+ if (size == -1 || size > 127)
+ {
+ va_start(ap, msg);
+ if ((size = vasprintf(&t, msg, ap)) < 0)
+ {
+ va_end(ap);
+ return -1;
+ }
+ va_end(ap);
+ printbuf_memappend(p, t, size);
+ free(t);
+ return size;
+ }
+ else
+ {
+ printbuf_memappend(p, buf, size);
+ return size;
+ }
}
void printbuf_reset(struct printbuf *p)
{
- p->buf[0] = '\0';
- p->bpos = 0;
+ p->buf[0] = '\0';
+ p->bpos = 0;
}
void printbuf_free(struct printbuf *p)
{
- if(p) {
- free(p->buf);
- free(p);
- }
+ if (p)
+ {
+ free(p->buf);
+ free(p);
+ }
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/printbuf.h thunderbird-91.8.1+build1/comm/third_party/json-c/printbuf.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/printbuf.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/printbuf.h 2022-04-15 07:49:22.000000000 +0000
@@ -15,7 +15,7 @@
/**
* @file
- * @brief Internal string buffer handing. Unless you're writing a
+ * @brief Internal string buffer handing. Unless you're writing a
* json_object_to_json_string_fn implementation for use with
* json_object_set_serializer() direct use of this is not
* recommended.
@@ -23,19 +23,27 @@
#ifndef _printbuf_h_
#define _printbuf_h_
+#ifndef JSON_EXPORT
+#if defined(_MSC_VER)
+#define JSON_EXPORT __declspec(dllexport)
+#else
+#define JSON_EXPORT extern
+#endif
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
-struct printbuf {
- char *buf;
- int bpos;
- int size;
+struct printbuf
+{
+ char *buf;
+ int bpos;
+ int size;
};
typedef struct printbuf printbuf;
-extern struct printbuf*
-printbuf_new(void);
+JSON_EXPORT struct printbuf *printbuf_new(void);
/* As an optimization, printbuf_memappend_fast() is defined as a macro
* that handles copying data if the buffer is large enough; otherwise
@@ -45,17 +53,22 @@
* Your code should not use printbuf_memappend() directly unless it
* checks the return code. Use printbuf_memappend_fast() instead.
*/
-extern int
-printbuf_memappend(struct printbuf *p, const char *buf, int size);
+JSON_EXPORT int printbuf_memappend(struct printbuf *p, const char *buf, int size);
-#define printbuf_memappend_fast(p, bufptr, bufsize) \
-do { \
- if ((p->size - p->bpos) > bufsize) { \
- memcpy(p->buf + p->bpos, (bufptr), bufsize); \
- p->bpos += bufsize; \
- p->buf[p->bpos]= '\0'; \
- } else { printbuf_memappend(p, (bufptr), bufsize); } \
-} while (0)
+#define printbuf_memappend_fast(p, bufptr, bufsize) \
+ do \
+ { \
+ if ((p->size - p->bpos) > bufsize) \
+ { \
+ memcpy(p->buf + p->bpos, (bufptr), bufsize); \
+ p->bpos += bufsize; \
+ p->buf[p->bpos] = '\0'; \
+ } \
+ else \
+ { \
+ printbuf_memappend(p, (bufptr), bufsize); \
+ } \
+ } while (0)
#define printbuf_length(p) ((p)->bpos)
@@ -79,7 +92,7 @@
* sprintbuf()
*/
#define printbuf_strappend(pb, str) \
- printbuf_memappend ((pb), _printbuf_check_literal(str), sizeof(str) - 1)
+ printbuf_memappend((pb), _printbuf_check_literal(str), sizeof(str) - 1)
/**
* Set len bytes of the buffer to charvalue, starting at offset offset.
@@ -89,8 +102,7 @@
*
* If offset is -1, this starts at the end of the current data in the buffer.
*/
-extern int
-printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len);
+JSON_EXPORT int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len);
/**
* Formatted print to printbuf.
@@ -106,14 +118,11 @@
* printbuf_memappend()
* printbuf_strappend()
*/
-extern int
-sprintbuf(struct printbuf *p, const char *msg, ...);
+JSON_EXPORT int sprintbuf(struct printbuf *p, const char *msg, ...);
-extern void
-printbuf_reset(struct printbuf *p);
+JSON_EXPORT void printbuf_reset(struct printbuf *p);
-extern void
-printbuf_free(struct printbuf *p);
+JSON_EXPORT void printbuf_free(struct printbuf *p);
#ifdef __cplusplus
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/random_seed.c thunderbird-91.8.1+build1/comm/third_party/json-c/random_seed.c
--- thunderbird-91.7.0+build2/comm/third_party/json-c/random_seed.c 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/random_seed.c 2022-04-15 07:49:21.000000000 +0000
@@ -9,14 +9,13 @@
*
*/
+#include "random_seed.h"
+#include "config.h"
#include "strerror_override.h"
#include
-#include "config.h"
-#include "random_seed.h"
#define DEBUG_SEED(s)
-
#if defined ENABLE_RDRAND
/* cpuid */
@@ -26,20 +25,11 @@
static void do_cpuid(int regs[], int h)
{
- __asm__ __volatile__(
-#if defined __x86_64__
- "pushq %%rbx;\n"
-#else
- "pushl %%ebx;\n"
-#endif
- "cpuid;\n"
-#if defined __x86_64__
- "popq %%rbx;\n"
-#else
- "popl %%ebx;\n"
-#endif
- : "=a"(regs[0]), [ebx] "=r"(regs[1]), "=c"(regs[2]), "=d"(regs[3])
+ /* clang-format off */
+ __asm__ __volatile__("cpuid"
+ : "=a"(regs[0]), "=b"(regs[1]), "=c"(regs[2]), "=d"(regs[3])
: "a"(h));
+ /* clang-format on */
}
#elif defined _MSC_VER
@@ -53,12 +43,51 @@
#if HAS_X86_CPUID
-static int has_rdrand()
+static int get_rdrand_seed(void);
+
+/* Valid values are -1 (haven't tested), 0 (no), and 1 (yes). */
+static int _has_rdrand = -1;
+
+static int has_rdrand(void)
{
- // CPUID.01H:ECX.RDRAND[bit 30] == 1
- int regs[4];
- do_cpuid(regs, 1);
- return (regs[2] & (1 << 30)) != 0;
+ if (_has_rdrand != -1)
+ {
+ return _has_rdrand;
+ }
+
+ /* CPUID.01H:ECX.RDRAND[bit 30] == 1 */
+ int regs[4];
+ do_cpuid(regs, 1);
+ if (!(regs[2] & (1 << 30)))
+ {
+ _has_rdrand = 0;
+ return 0;
+ }
+
+ /*
+ * Some CPUs advertise RDRAND in CPUID, but return 0xFFFFFFFF
+ * unconditionally. To avoid locking up later, test RDRAND here. If over
+ * 3 trials RDRAND has returned the same value, declare it broken.
+ * Example CPUs are AMD Ryzen 3000 series
+ * and much older AMD APUs, such as the E1-1500
+ * https://github.com/systemd/systemd/issues/11810
+ * https://linuxreviews.org/RDRAND_stops_returning_random_values_on_older_AMD_CPUs_after_suspend
+ */
+ _has_rdrand = 0;
+ int prev = get_rdrand_seed();
+ for (int i = 0; i < 3; i++)
+ {
+ int temp = get_rdrand_seed();
+ if (temp != prev)
+ {
+ _has_rdrand = 1;
+ break;
+ }
+
+ prev = temp;
+ }
+
+ return _has_rdrand;
}
#endif
@@ -69,17 +98,19 @@
#define HAVE_RDRAND 1
-static int get_rdrand_seed()
+static int get_rdrand_seed(void)
{
- DEBUG_SEED("get_rdrand_seed");
- int _eax;
- // rdrand eax
- __asm__ __volatile__("1: .byte 0x0F\n"
- " .byte 0xC7\n"
- " .byte 0xF0\n"
- " jnc 1b;\n"
- : "=a" (_eax));
- return _eax;
+ DEBUG_SEED("get_rdrand_seed");
+ int _eax;
+ /* rdrand eax */
+ /* clang-format off */
+ __asm__ __volatile__("1: .byte 0x0F\n"
+ " .byte 0xC7\n"
+ " .byte 0xF0\n"
+ " jnc 1b;\n"
+ : "=a" (_eax));
+ /* clang-format on */
+ return _eax;
}
#endif
@@ -91,12 +122,13 @@
/* get_rdrand_seed - Visual Studio 2012 and above */
-static int get_rdrand_seed()
+static int get_rdrand_seed(void)
{
- DEBUG_SEED("get_rdrand_seed");
- int r;
- while (_rdrand32_step(&r) == 0);
- return r;
+ DEBUG_SEED("get_rdrand_seed");
+ int r;
+ while (_rdrand32_step(&r) == 0)
+ ;
+ return r;
}
#elif defined _M_IX86
@@ -104,31 +136,34 @@
/* get_rdrand_seed - Visual Studio 2010 and below - x86 only */
-static int get_rdrand_seed()
+/* clang-format off */
+static int get_rdrand_seed(void)
{
DEBUG_SEED("get_rdrand_seed");
int _eax;
retry:
- // rdrand eax
+ /* rdrand eax */
__asm _emit 0x0F __asm _emit 0xC7 __asm _emit 0xF0
__asm jnc retry
__asm mov _eax, eax
return _eax;
}
+/* clang-format on */
#endif
#endif
#endif /* defined ENABLE_RDRAND */
-
/* has_dev_urandom */
-#if defined (__APPLE__) || defined(__unix__) || defined(__linux__)
+#if defined(__APPLE__) || defined(__unix__) || defined(__linux__)
-#include
#include
+#include
+#if HAVE_UNISTD_H
#include
+#endif /* HAVE_UNISTD_H */
#include
#include
@@ -136,103 +171,124 @@
static const char *dev_random_file = "/dev/urandom";
-static int has_dev_urandom()
+static int has_dev_urandom(void)
{
- struct stat buf;
- if (stat(dev_random_file, &buf)) {
- return 0;
- }
- return ((buf.st_mode & S_IFCHR) != 0);
+ struct stat buf;
+ if (stat(dev_random_file, &buf))
+ {
+ return 0;
+ }
+ return ((buf.st_mode & S_IFCHR) != 0);
}
-
/* get_dev_random_seed */
-static int get_dev_random_seed()
+static int get_dev_random_seed(void)
{
- DEBUG_SEED("get_dev_random_seed");
+ DEBUG_SEED("get_dev_random_seed");
- int fd = open(dev_random_file, O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno));
- exit(1);
- }
-
- int r;
- ssize_t nread = read(fd, &r, sizeof(r));
- if (nread != sizeof(r)) {
- fprintf(stderr, "error short read %s: %s", dev_random_file, strerror(errno));
- exit(1);
- }
+ int fd = open(dev_random_file, O_RDONLY);
+ if (fd < 0)
+ {
+ fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno));
+ exit(1);
+ }
+
+ int r;
+ ssize_t nread = read(fd, &r, sizeof(r));
+ if (nread != sizeof(r))
+ {
+ fprintf(stderr, "error short read %s: %s", dev_random_file, strerror(errno));
+ exit(1);
+ }
- close(fd);
- return r;
+ close(fd);
+ return r;
}
#endif
-
/* get_cryptgenrandom_seed */
#ifdef WIN32
#define HAVE_CRYPTGENRANDOM 1
+/* clang-format off */
#include
+
+/* Caution: these blank lines must remain so clang-format doesn't reorder
+ includes to put windows.h after wincrypt.h */
+
#include
+/* clang-format on */
#ifndef __GNUC__
#pragma comment(lib, "advapi32.lib")
#endif
-static int get_cryptgenrandom_seed()
-{
- HCRYPTPROV hProvider = 0;
- int r;
-
- DEBUG_SEED("get_cryptgenrandom_seed");
-
- if (!CryptAcquireContextW(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
- fprintf(stderr, "error CryptAcquireContextW");
- exit(1);
- }
+static int get_time_seed(void);
- if (!CryptGenRandom(hProvider, sizeof(r), (BYTE*)&r)) {
- fprintf(stderr, "error CryptGenRandom");
- exit(1);
- }
-
- CryptReleaseContext(hProvider, 0);
+static int get_cryptgenrandom_seed(void)
+{
+ HCRYPTPROV hProvider = 0;
+ DWORD dwFlags = CRYPT_VERIFYCONTEXT;
+ int r;
+
+ DEBUG_SEED("get_cryptgenrandom_seed");
+
+ /* WinNT 4 and Win98 do no support CRYPT_SILENT */
+ if (LOBYTE(LOWORD(GetVersion())) > 4)
+ dwFlags |= CRYPT_SILENT;
+
+ if (!CryptAcquireContextA(&hProvider, 0, 0, PROV_RSA_FULL, dwFlags))
+ {
+ fprintf(stderr, "error CryptAcquireContextA 0x%08lx", GetLastError());
+ r = get_time_seed();
+ }
+ else
+ {
+ BOOL ret = CryptGenRandom(hProvider, sizeof(r), (BYTE*)&r);
+ CryptReleaseContext(hProvider, 0);
+ if (!ret)
+ {
+ fprintf(stderr, "error CryptGenRandom 0x%08lx", GetLastError());
+ r = get_time_seed();
+ }
+ }
- return r;
+ return r;
}
#endif
-
/* get_time_seed */
#include
-static int get_time_seed()
+static int get_time_seed(void)
{
- DEBUG_SEED("get_time_seed");
+ DEBUG_SEED("get_time_seed");
- return (int)time(NULL) * 433494437;
+ return (int)time(NULL) * 433494437;
}
-
/* json_c_get_random_seed */
-int json_c_get_random_seed()
+int json_c_get_random_seed(void)
{
-#if HAVE_RDRAND
- if (has_rdrand()) return get_rdrand_seed();
+#ifdef OVERRIDE_GET_RANDOM_SEED
+ OVERRIDE_GET_RANDOM_SEED;
+#endif
+#if defined HAVE_RDRAND && HAVE_RDRAND
+ if (has_rdrand())
+ return get_rdrand_seed();
#endif
-#if HAVE_DEV_RANDOM
- if (has_dev_urandom()) return get_dev_random_seed();
+#if defined HAVE_DEV_RANDOM && HAVE_DEV_RANDOM
+ if (has_dev_urandom())
+ return get_dev_random_seed();
#endif
-#if HAVE_CRYPTGENRANDOM
- return get_cryptgenrandom_seed();
+#if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM
+ return get_cryptgenrandom_seed();
#endif
- return get_time_seed();
+ return get_time_seed();
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/random_seed.h thunderbird-91.8.1+build1/comm/third_party/json-c/random_seed.h
--- thunderbird-91.7.0+build2/comm/third_party/json-c/random_seed.h 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/random_seed.h 2022-04-15 07:49:21.000000000 +0000
@@ -20,7 +20,7 @@
extern "C" {
#endif
-extern int json_c_get_random_seed();
+extern int json_c_get_random_seed(void);
#ifdef __cplusplus
}
diff -Nru thunderbird-91.7.0+build2/comm/third_party/json-c/README.html thunderbird-91.8.1+build1/comm/third_party/json-c/README.html
--- thunderbird-91.7.0+build2/comm/third_party/json-c/README.html 2022-03-07 21:35:20.000000000 +0000
+++ thunderbird-91.8.1+build1/comm/third_party/json-c/README.html 2022-04-15 07:49:21.000000000 +0000
@@ -8,8 +8,8 @@
JSON-C - A JSON implementation in C
Overview
-
JSON-C implements a reference counting object model that allows you to easily
- construct JSON objects in C, output them as JSON formatted strings and parse
+
JSON-C implements a reference counting object model that allows you to easily
+ construct JSON objects in C, output them as JSON formatted strings and parse
JSON formatted strings back into the C representation of JSON objects.
It aims to conform to RFC 7159.
@@ -26,8 +26,7 @@
Documentation
-
Doxygen generated documentation exists here
- and Win32 specific notes can be found here.