diff --git a/browser/components/extensions/ext-windows.js b/browser/components/extensions/ext-windows.js index fbc7045e3a58..806a99796940 100644 --- a/browser/components/extensions/ext-windows.js +++ b/browser/components/extensions/ext-windows.js @@ -39,12 +39,16 @@ extensions.registerSchemaAPI("windows", "addon_parent", context => { let lastOnFocusChangedWindowId; let listener = event => { - let window = WindowManager.topWindow; - let windowId = window ? WindowManager.getId(window) : WindowManager.WINDOW_ID_NONE; - if (windowId !== lastOnFocusChangedWindowId) { - fire(windowId); - lastOnFocusChangedWindowId = windowId; - } + // Wait a tick to avoid firing a superfluous WINDOW_ID_NONE + // event when switching focus between two Firefox windows. + Promise.resolve().then(() => { + let window = Services.focus.activeWindow; + let windowId = window ? WindowManager.getId(window) : WindowManager.WINDOW_ID_NONE; + if (windowId !== lastOnFocusChangedWindowId) { + fire(windowId); + lastOnFocusChangedWindowId = windowId; + } + }); }; AllWindowEvents.addListener("focus", listener); AllWindowEvents.addListener("blur", listener); diff --git a/browser/components/extensions/test/browser/browser_ext_windows_events.js b/browser/components/extensions/test/browser/browser_ext_windows_events.js index aa3467e8ea09..ac152b084837 100644 --- a/browser/components/extensions/test/browser/browser_ext_windows_events.js +++ b/browser/components/extensions/test/browser/browser_ext_windows_events.js @@ -16,10 +16,15 @@ add_task(function* testWindowsEvents() { browser.test.sendMessage("window-created", window.id); }); - let lastWindowId; + let lastWindowId, os; browser.windows.onFocusChanged.addListener(function listener(windowId) { browser.test.log(`onFocusChange: windowId=${windowId} lastWindowId=${lastWindowId}`); + if (windowId === browser.windows.WINDOW_ID_NONE && os === "linux") { + browser.test.log("Ignoring a superfluous WINDOW_ID_NONE (blur) event on Linux"); + return; + } + browser.test.assertTrue(lastWindowId !== windowId, "onFocusChanged fired once for the given window"); lastWindowId = windowId; @@ -43,7 +48,10 @@ add_task(function* testWindowsEvents() { browser.test.notifyPass("windows.events"); }); - browser.test.sendMessage("ready"); + browser.runtime.getPlatformInfo(info => { + os = info.os; + browser.test.sendMessage("ready"); + }); } let extension = ExtensionTestUtils.loadExtension({ diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 5e27e73728f6..2a60221726dd 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -154,8 +154,8 @@ inline void SetPendingExceptionASCII(JSContext *cx, const char *aMsg) inline void SetPendingException(JSContext *cx, const char16_t *aMsg) { - // FIXME: Need to convert to UTF-8 (bug XXX). - JS_ReportErrorLatin1(cx, "%hs", aMsg); + NS_ConvertUTF16toUTF8 msg(aMsg); + JS_ReportErrorUTF8(cx, "%s", msg.get()); } // Helper class to get stuff from the ClassInfo and not waste extra time with diff --git a/devtools/client/animationinspector/test/browser.ini b/devtools/client/animationinspector/test/browser.ini index c8d111b120db..8d6343612f24 100644 --- a/devtools/client/animationinspector/test/browser.ini +++ b/devtools/client/animationinspector/test/browser.ini @@ -48,8 +48,9 @@ skip-if = os == "linux" && !debug # Bug 1227792 [browser_animation_timeline_currentTime.js] [browser_animation_timeline_header.js] [browser_animation_timeline_iterationStart.js] -[browser_animation_timeline_pause_button.js] -skip-if = os == "linux" && bits == 32 # Bug 1220974 +[browser_animation_timeline_pause_button_01.js] +[browser_animation_timeline_pause_button_02.js] +[browser_animation_timeline_pause_button_03.js] [browser_animation_timeline_rate_selector.js] [browser_animation_timeline_rewind_button.js] [browser_animation_timeline_scrubber_exists.js] diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js deleted file mode 100644 index 4bded733ac7f..000000000000 --- a/devtools/client/animationinspector/test/browser_animation_timeline_pause_button.js +++ /dev/null @@ -1,110 +0,0 @@ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -requestLongerTimeout(2); - -// Check that the timeline toolbar contains a pause button and that this pause -// button can be clicked. Check that when it is, the current animations -// displayed in the timeline get their playstates changed accordingly, and check -// that the scrubber resumes/stops moving. -// Also checks that the button goes to the right state when the scrubber has -// reached the end of the timeline: continues to be in playing mode for infinite -// animations, goes to paused mode otherwise. -// And test that clicking the button once the scrubber has reached the end of -// the timeline does the right thing. - -add_task(function* () { - yield addTab(URL_ROOT + "doc_simple_animation.html"); - - let {panel, inspector} = yield openAnimationInspector(); - let timeline = panel.animationsTimelineComponent; - let btn = panel.playTimelineButtonEl; - - ok(btn, "The play/pause button exists"); - ok(!btn.classList.contains("paused"), - "The play/pause button is in its playing state"); - - info("Click on the button to pause all timeline animations"); - yield clickTimelinePlayPauseButton(panel); - - ok(btn.classList.contains("paused"), - "The play/pause button is in its paused state"); - yield assertScrubberMoving(panel, false); - - info("Click again on the button to play all timeline animations"); - yield clickTimelinePlayPauseButton(panel); - - ok(!btn.classList.contains("paused"), - "The play/pause button is in its playing state again"); - yield assertScrubberMoving(panel, true); - - // Some animations on the test page are infinite, so the scrubber won't stop - // at the end of the timeline, and the button should remain in play mode. - info("Select an infinite animation, reload the page and wait for the " + - "animation to complete"); - yield selectNodeAndWaitForAnimations(".multi", inspector); - yield reloadTab(inspector); - yield waitForOutOfBoundScrubber(timeline); - - ok(!btn.classList.contains("paused"), - "The button is in its playing state still, animations are infinite."); - yield assertScrubberMoving(panel, true); - - info("Click on the button after the scrubber has moved out of bounds"); - yield clickTimelinePlayPauseButton(panel); - - ok(btn.classList.contains("paused"), - "The button can be paused after the scrubber has moved out of bounds"); - yield assertScrubberMoving(panel, false); - - // For a finite animation though, once the scrubber reaches the end of the - // timeline, it should go back to paused mode. - info("Select a finite animation, reload the page and wait for the " + - "animation to complete"); - yield selectNodeAndWaitForAnimations(".negative-delay", inspector); - - let onScrubberStopped = waitForScrubberStopped(timeline); - yield reloadTab(inspector); - yield onScrubberStopped; - - ok(btn.classList.contains("paused"), - "The button is in paused state once finite animations are done"); - yield assertScrubberMoving(panel, false); - - info("Click again on the button to play the animation from the start again"); - yield clickTimelinePlayPauseButton(panel); - - ok(!btn.classList.contains("paused"), - "Clicking the button once finite animations are done should restart them"); - yield assertScrubberMoving(panel, true); -}); - -function waitForOutOfBoundScrubber({win, scrubberEl}) { - return new Promise(resolve => { - function check() { - let pos = scrubberEl.getBoxQuads()[0].bounds.right; - let width = win.document.documentElement.offsetWidth; - if (pos >= width) { - setTimeout(resolve, 50); - } else { - setTimeout(check, 50); - } - } - check(); - }); -} - -function waitForScrubberStopped(timeline) { - return new Promise(resolve => { - timeline.on("timeline-data-changed", - function onTimelineData(e, {isMoving}) { - if (!isMoving) { - timeline.off("timeline-data-changed", onTimelineData); - resolve(); - } - }); - }); -} diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_01.js b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_01.js new file mode 100644 index 000000000000..a3a2b4c61003 --- /dev/null +++ b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_01.js @@ -0,0 +1,34 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +requestLongerTimeout(2); + +// Check that the timeline toolbar contains a pause button and that this pause button can +// be clicked. Check that when it is, the button changes state and the scrubber stops and +// resumes. + +add_task(function* () { + yield addTab(URL_ROOT + "doc_simple_animation.html"); + + let {panel} = yield openAnimationInspector(); + let btn = panel.playTimelineButtonEl; + + ok(btn, "The play/pause button exists"); + ok(!btn.classList.contains("paused"), "The play/pause button is in its playing state"); + + info("Click on the button to pause all timeline animations"); + yield clickTimelinePlayPauseButton(panel); + + ok(btn.classList.contains("paused"), "The play/pause button is in its paused state"); + yield assertScrubberMoving(panel, false); + + info("Click again on the button to play all timeline animations"); + yield clickTimelinePlayPauseButton(panel); + + ok(!btn.classList.contains("paused"), + "The play/pause button is in its playing state again"); + yield assertScrubberMoving(panel, true); +}); diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_02.js b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_02.js new file mode 100644 index 000000000000..1c440dd8815b --- /dev/null +++ b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_02.js @@ -0,0 +1,48 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +requestLongerTimeout(2); + +// Checks that the play/pause button goes to the right state when the scrubber has reached +// the end of the timeline but there are infinite animations playing. + +add_task(function* () { + yield addTab(URL_ROOT + "doc_simple_animation.html"); + + let {panel, inspector} = yield openAnimationInspector(); + let timeline = panel.animationsTimelineComponent; + let btn = panel.playTimelineButtonEl; + + info("Select an infinite animation and wait for the scrubber to reach the end"); + yield selectNodeAndWaitForAnimations(".multi", inspector); + yield waitForOutOfBoundScrubber(timeline); + + ok(!btn.classList.contains("paused"), + "The button is in its playing state still, animations are infinite."); + yield assertScrubberMoving(panel, true); + + info("Click on the button after the scrubber has moved out of bounds"); + yield clickTimelinePlayPauseButton(panel); + + ok(btn.classList.contains("paused"), + "The button can be paused after the scrubber has moved out of bounds"); + yield assertScrubberMoving(panel, false); +}); + +function waitForOutOfBoundScrubber({win, scrubberEl}) { + return new Promise(resolve => { + function check() { + let pos = scrubberEl.getBoxQuads()[0].bounds.right; + let width = win.document.documentElement.offsetWidth; + if (pos >= width) { + setTimeout(resolve, 50); + } else { + setTimeout(check, 50); + } + } + check(); + }); +} diff --git a/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_03.js b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_03.js new file mode 100644 index 000000000000..ad75ab9f79b5 --- /dev/null +++ b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_03.js @@ -0,0 +1,54 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +requestLongerTimeout(2); + +// Also checks that the button goes to the right state when the scrubber has +// reached the end of the timeline: continues to be in playing mode for infinite +// animations, goes to paused mode otherwise. +// And test that clicking the button once the scrubber has reached the end of +// the timeline does the right thing. + +add_task(function* () { + yield addTab(URL_ROOT + "doc_simple_animation.html"); + + let {panel, inspector} = yield openAnimationInspector(); + let timeline = panel.animationsTimelineComponent; + let btn = panel.playTimelineButtonEl; + + // For a finite animation, once the scrubber reaches the end of the timeline, the pause + // button should go back to paused mode. + info("Select a finite animation and wait for the animation to complete"); + yield selectNodeAndWaitForAnimations(".negative-delay", inspector); + + let onScrubberStopped = waitForScrubberStopped(timeline); + // The page is reloaded to avoid missing the animation. + yield reloadTab(inspector); + yield onScrubberStopped; + + ok(btn.classList.contains("paused"), + "The button is in paused state once finite animations are done"); + yield assertScrubberMoving(panel, false); + + info("Click again on the button to play the animation from the start again"); + yield clickTimelinePlayPauseButton(panel); + + ok(!btn.classList.contains("paused"), + "Clicking the button once finite animations are done should restart them"); + yield assertScrubberMoving(panel, true); +}); + +function waitForScrubberStopped(timeline) { + return new Promise(resolve => { + timeline.on("timeline-data-changed", + function onTimelineData(e, {isMoving}) { + if (!isMoving) { + timeline.off("timeline-data-changed", onTimelineData); + resolve(); + } + }); + }); +} diff --git a/devtools/client/themes/inspector.css b/devtools/client/themes/inspector.css index b009e4e16810..9590d5367fa8 100644 --- a/devtools/client/themes/inspector.css +++ b/devtools/client/themes/inspector.css @@ -105,24 +105,6 @@ window { flex: unset; } -/* TODO: bug 1265759: should apply to .devtools-searchinput once all searchbox - is converted to html*/ -#inspector-searchbox { - width: 100%; -} - -/* Make sure the text is vertically centered in Inspector's - search box. This can be removed when the search box is - switched to HTML. - See also: https://bugzilla.mozilla.org/show_bug.cgi?id=1265759 */ -.theme-dark #inspector-searchbox, -.theme-light #inspector-searchbox { - line-height: 19px; -} -.theme-firebug #inspector-searchbox { - line-height: 17px; -} - /* Eyedropper toolbar button */ #inspector-eyedropper-toggle { diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index 020cffd4e69c..d9377a70604d 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -638,7 +638,7 @@ ThrowJSExceptionASCII(JSContext *cx, const char *message) PopException(); } else { - ::JS_ReportErrorASCII(cx, message); + ::JS_ReportErrorASCII(cx, "%s", message); } } diff --git a/js/src/asmjs/AsmJS.cpp b/js/src/asmjs/AsmJS.cpp index 545a95a37842..e375b49bcb7a 100644 --- a/js/src/asmjs/AsmJS.cpp +++ b/js/src/asmjs/AsmJS.cpp @@ -2250,7 +2250,7 @@ class MOZ_STACK_CLASS ModuleValidator return false; } - bool failfOffset(uint32_t offset, const char* fmt, ...) { + bool failfOffset(uint32_t offset, const char* fmt, ...) MOZ_FORMAT_PRINTF(3, 4) { va_list ap; va_start(ap, fmt); failfVAOffset(offset, fmt, ap); @@ -2258,7 +2258,7 @@ class MOZ_STACK_CLASS ModuleValidator return false; } - bool failf(ParseNode* pn, const char* fmt, ...) { + bool failf(ParseNode* pn, const char* fmt, ...) MOZ_FORMAT_PRINTF(3, 4) { va_list ap; va_start(ap, fmt); failfVAOffset(pn->pn_pos.begin, fmt, ap); @@ -2944,7 +2944,7 @@ class MOZ_STACK_CLASS FunctionValidator return m_.fail(pn, str); } - bool failf(ParseNode* pn, const char* fmt, ...) { + bool failf(ParseNode* pn, const char* fmt, ...) MOZ_FORMAT_PRINTF(3, 4) { va_list ap; va_start(ap, fmt); m_.failfVAOffset(pn->pn_pos.begin, fmt, ap); @@ -4720,7 +4720,8 @@ static bool CheckSignatureAgainstExisting(ModuleValidator& m, ParseNode* usepn, const Sig& sig, const Sig& existing) { if (sig.args().length() != existing.args().length()) { - return m.failf(usepn, "incompatible number of arguments (%u here vs. %u before)", + return m.failf(usepn, "incompatible number of arguments (%" PRIuSIZE + " here vs. %" PRIuSIZE " before)", sig.args().length(), existing.args().length()); } diff --git a/js/src/asmjs/WasmBinary.cpp b/js/src/asmjs/WasmBinary.cpp index 4c1946583a6c..c14ad19dbc87 100644 --- a/js/src/asmjs/WasmBinary.cpp +++ b/js/src/asmjs/WasmBinary.cpp @@ -41,7 +41,8 @@ Decoder::fail(const char* msg, ...) { bool Decoder::fail(UniqueChars msg) { MOZ_ASSERT(error_); - UniqueChars strWithOffset(JS_smprintf("at offset %zu: %s", currentOffset(), msg.get())); + UniqueChars strWithOffset(JS_smprintf("at offset %" PRIuSIZE ": %s", + currentOffset(), msg.get())); if (!strWithOffset) return false; @@ -57,7 +58,7 @@ wasm::DecodePreamble(Decoder& d) return d.fail("failed to match magic number"); if (!d.readFixedU32(&u32) || u32 != EncodingVersion) - return d.fail("binary version 0x%lx does not match expected version 0x%lx", + return d.fail("binary version 0x%" PRIx32 " does not match expected version 0x%" PRIx32, u32, EncodingVersion); return true; @@ -151,7 +152,7 @@ wasm::DecodeLimits(Decoder& d, Limits* limits) // TODO (bug 1310149): tighten this check (s/3/1) when the AngryBots demo // gets updated. if (flags & ~uint32_t(0x3)) - return d.fail("unexpected bits set in flags: %lu", (flags & ~uint32_t(0x3))); + return d.fail("unexpected bits set in flags: %" PRIu32, (flags & ~uint32_t(0x3))); if (!d.readVarU32(&limits->initial)) return d.fail("expected initial length"); @@ -163,7 +164,7 @@ wasm::DecodeLimits(Decoder& d, Limits* limits) if (limits->initial > maximum) { return d.fail("memory size minimum must not be greater than maximum; " - "maximum length %lu is less than initial length %lu", + "maximum length %" PRIu32 " is less than initial length %" PRIu32 , maximum, limits->initial); } diff --git a/js/src/asmjs/WasmBinary.h b/js/src/asmjs/WasmBinary.h index b81121a8b42e..40ad205f73f3 100644 --- a/js/src/asmjs/WasmBinary.h +++ b/js/src/asmjs/WasmBinary.h @@ -778,7 +778,7 @@ class Decoder error_(error) {} - bool fail(const char* msg, ...); + bool fail(const char* msg, ...) MOZ_FORMAT_PRINTF(2, 3); bool fail(UniqueChars msg); void clearError() { if (error_) diff --git a/js/src/asmjs/WasmBinaryIterator.h b/js/src/asmjs/WasmBinaryIterator.h index 9a9bf1edfa06..ae244044225c 100644 --- a/js/src/asmjs/WasmBinaryIterator.h +++ b/js/src/asmjs/WasmBinaryIterator.h @@ -725,7 +725,7 @@ template bool ExprIter::fail(const char* msg) { - return d_.fail(msg); + return d_.fail("%s", msg); } template diff --git a/js/src/asmjs/WasmCode.cpp b/js/src/asmjs/WasmCode.cpp index 3b0b37c8c1af..619dba2b921e 100644 --- a/js/src/asmjs/WasmCode.cpp +++ b/js/src/asmjs/WasmCode.cpp @@ -796,8 +796,10 @@ Code::ensureProfilingState(JSContext* cx, bool newProfilingEnabled) if (!name.append('\0')) return false; - UniqueChars label(JS_smprintf("%hs (%s:%u)", - name.begin(), + TwoByteChars chars(name.begin(), name.length()); + UniqueChars utf8Name(JS::CharsToNewUTF8CharsZ(nullptr, chars).c_str()); + UniqueChars label(JS_smprintf("%s (%s:%u)", + utf8Name.get(), metadata_->filename.get(), codeRange.funcLineOrBytecode())); if (!label) { diff --git a/js/src/asmjs/WasmTextToBinary.cpp b/js/src/asmjs/WasmTextToBinary.cpp index 822654924e8f..6ac574544680 100644 --- a/js/src/asmjs/WasmTextToBinary.cpp +++ b/js/src/asmjs/WasmTextToBinary.cpp @@ -1488,7 +1488,7 @@ struct WasmParseContext {} bool fail(const char* message) { - error->reset(JS_smprintf(message)); + error->reset(js_strdup(message)); return false; } ~WasmParseContext() { @@ -3336,12 +3336,9 @@ class Resolver return false; } bool failResolveLabel(const char* kind, AstName name) { - Vector nameWithNull; - if (!nameWithNull.append(name.begin(), name.length())) - return false; - if (!nameWithNull.append(0)) - return false; - error_->reset(JS_smprintf("%s label '%hs' not found", kind, nameWithNull.begin())); + TwoByteChars chars(name.begin(), name.length()); + UniqueChars utf8Chars(CharsToNewUTF8CharsZ(nullptr, chars).c_str()); + error_->reset(JS_smprintf("%s label '%s' not found", kind, utf8Chars.get())); return false; } diff --git a/js/src/builtin/Profilers.cpp b/js/src/builtin/Profilers.cpp index 227891d88092..0d30a1c6b09f 100644 --- a/js/src/builtin/Profilers.cpp +++ b/js/src/builtin/Profilers.cpp @@ -41,9 +41,7 @@ static char gLastError[2000]; #if defined(__APPLE__) || defined(__linux__) || defined(MOZ_CALLGRIND) static void -#ifdef __GNUC__ -__attribute__((format(printf,1,2))) -#endif +MOZ_FORMAT_PRINTF(1, 2) UnsafeError(const char* format, ...) { va_list args; diff --git a/js/src/devtools/gctrace/gcstats.cpp b/js/src/devtools/gctrace/gcstats.cpp index 9b7d22247aef..865e65839dea 100644 --- a/js/src/devtools/gctrace/gcstats.cpp +++ b/js/src/devtools/gctrace/gcstats.cpp @@ -165,6 +165,7 @@ Array, MaxClasses> finalizedHeapObjectCountByCl std::vector, HeapKinds> > objectCountByTypeHeapAndLifetime; static void +MOZ_FORMAT_PRINTF(1, 2) die(const char* format, ...) { va_list va; diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp index 416ec000c316..4b6138b7661b 100644 --- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -535,7 +535,7 @@ CheckHeapTracer::check(AutoLockForExclusiveAccess& lock) return; if (failures) { - fprintf(stderr, "Heap check: %zu failure(s) out of %" PRIu32 " pointers checked\n", + fprintf(stderr, "Heap check: %" PRIuSIZE " failure(s) out of %" PRIu32 " pointers checked\n", failures, visited.count()); } MOZ_RELEASE_ASSERT(failures == 0); diff --git a/js/src/irregexp/RegExpEngine.cpp b/js/src/irregexp/RegExpEngine.cpp index 623525d2215a..bc556b4a1ef2 100644 --- a/js/src/irregexp/RegExpEngine.cpp +++ b/js/src/irregexp/RegExpEngine.cpp @@ -1872,7 +1872,7 @@ irregexp::CompilePattern(JSContext* cx, RegExpShared* shared, RegExpCompileData* Analysis analysis(cx, ignore_case, is_ascii, unicode); analysis.EnsureAnalyzed(node); if (analysis.has_failed()) { - JS_ReportErrorASCII(cx, analysis.errorMessage()); + JS_ReportErrorASCII(cx, "%s", analysis.errorMessage()); return RegExpCode(); } diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index 8d2bca22bf67..bb5dfac3624f 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -1245,7 +1245,7 @@ bool BacktrackingAllocator::processBundle(MIRGenerator* mir, LiveBundle* bundle) { if (JitSpewEnabled(JitSpew_RegAlloc)) { - JitSpew(JitSpew_RegAlloc, "Allocating %s [priority %lu] [weight %lu]", + JitSpew(JitSpew_RegAlloc, "Allocating %s [priority %" PRIuSIZE "] [weight %" PRIuSIZE "]", bundle->toString().get(), computePriority(bundle), computeSpillWeight(bundle)); } @@ -1437,13 +1437,13 @@ BacktrackingAllocator::tryAllocateRegister(PhysicalRegister& r, LiveBundle* bund if (JitSpewEnabled(JitSpew_RegAlloc)) { if (aliasedConflicting.length() == 1) { LiveBundle* existing = aliasedConflicting[0]; - JitSpew(JitSpew_RegAlloc, " %s collides with %s [weight %lu]", + JitSpew(JitSpew_RegAlloc, " %s collides with %s [weight %" PRIuSIZE "]", r.reg.name(), existing->toString().get(), computeSpillWeight(existing)); } else { JitSpew(JitSpew_RegAlloc, " %s collides with the following", r.reg.name()); for (size_t i = 0; i < aliasedConflicting.length(); i++) { LiveBundle* existing = aliasedConflicting[i]; - JitSpew(JitSpew_RegAlloc, " %s [weight %lu]", + JitSpew(JitSpew_RegAlloc, " %s [weight %" PRIuSIZE "]", existing->toString().get(), computeSpillWeight(existing)); } } @@ -1482,7 +1482,7 @@ bool BacktrackingAllocator::evictBundle(LiveBundle* bundle) { if (JitSpewEnabled(JitSpew_RegAlloc)) { - JitSpew(JitSpew_RegAlloc, " Evicting %s [priority %lu] [weight %lu]", + JitSpew(JitSpew_RegAlloc, " Evicting %s [priority %" PRIuSIZE "] [weight %" PRIuSIZE "]", bundle->toString().get(), computePriority(bundle), computeSpillWeight(bundle)); } @@ -2296,7 +2296,8 @@ LiveBundle::toString() const { AutoEnterOOMUnsafeRegion oomUnsafe; - char *buf = JS_smprintf(""); + // Suppress -Wformat warning. + char *buf = JS_smprintf("%s", ""); for (LiveRange::BundleLinkIterator iter = rangesBegin(); buf && iter; iter++) { buf = JS_sprintf_append(buf, "%s %s", diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index 4c990b61de55..0b081c265483 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -230,11 +230,11 @@ struct BaselineStackBuilder if (info) { if (sizeof(size_t) == 4) { JitSpew(JitSpew_BaselineBailouts, - " WRITE_WRD %p/%p %-15s %08x", + " WRITE_WRD %p/%p %-15s %08" PRIxSIZE, header_->copyStackBottom, virtualPointerAtStackOffset(0), info, w); } else { JitSpew(JitSpew_BaselineBailouts, - " WRITE_WRD %p/%p %-15s %016llx", + " WRITE_WRD %p/%p %-15s %016" PRIxSIZE, header_->copyStackBottom, virtualPointerAtStackOffset(0), info, w); } } @@ -246,7 +246,7 @@ struct BaselineStackBuilder return false; if (info) { JitSpew(JitSpew_BaselineBailouts, - " WRITE_VAL %p/%p %-15s %016llx", + " WRITE_VAL %p/%p %-15s %016" PRIx64, header_->copyStackBottom, virtualPointerAtStackOffset(0), info, *((uint64_t*) &val)); } @@ -637,7 +637,7 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC, // | ReturnAddr | <-- return into main jitcode after IC // +===============+ - JitSpew(JitSpew_BaselineBailouts, " Unpacking %s:%d", script->filename(), script->lineno()); + JitSpew(JitSpew_BaselineBailouts, " Unpacking %s:%" PRIuSIZE, script->filename(), script->lineno()); JitSpew(JitSpew_BaselineBailouts, " [BASELINE-JS FRAME]"); // Calculate and write the previous frame pointer value. @@ -749,7 +749,7 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC, } JitSpew(JitSpew_BaselineBailouts, " EnvChain=%p", envChain); blFrame->setEnvironmentChain(envChain); - JitSpew(JitSpew_BaselineBailouts, " ReturnValue=%016llx", *((uint64_t*) &returnValue)); + JitSpew(JitSpew_BaselineBailouts, " ReturnValue=%016" PRIx64, *((uint64_t*) &returnValue)); blFrame->setReturnValue(returnValue); // Do not need to initialize scratchValue field in BaselineFrame. @@ -764,13 +764,13 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC, // in the calling frame. Value thisv = iter.read(); JitSpew(JitSpew_BaselineBailouts, " Is function!"); - JitSpew(JitSpew_BaselineBailouts, " thisv=%016llx", *((uint64_t*) &thisv)); + JitSpew(JitSpew_BaselineBailouts, " thisv=%016" PRIx64, *((uint64_t*) &thisv)); size_t thisvOffset = builder.framePushed() + JitFrameLayout::offsetOfThis(); builder.valuePointerAtStackOffset(thisvOffset).set(thisv); MOZ_ASSERT(iter.numAllocations() >= CountArgSlots(script, fun)); - JitSpew(JitSpew_BaselineBailouts, " frame slots %u, nargs %u, nfixed %u", + JitSpew(JitSpew_BaselineBailouts, " frame slots %u, nargs %" PRIuSIZE ", nfixed %" PRIuSIZE, iter.numAllocations(), fun->nargs(), script->nfixed()); if (!callerPC) { @@ -786,7 +786,7 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC, for (uint32_t i = 0; i < fun->nargs(); i++) { Value arg = iter.read(); - JitSpew(JitSpew_BaselineBailouts, " arg %d = %016llx", + JitSpew(JitSpew_BaselineBailouts, " arg %d = %016" PRIx64, (int) i, *((uint64_t*) &arg)); if (callerPC) { size_t argOffset = builder.framePushed() + JitFrameLayout::offsetOfActualArg(i); @@ -1314,7 +1314,7 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC, return false; // Push callee token (must be a JS Function) - JitSpew(JitSpew_BaselineBailouts, " Callee = %016llx", callee.asRawBits()); + JitSpew(JitSpew_BaselineBailouts, " Callee = %016" PRIx64, callee.asRawBits()); JSFunction* calleeFun = &callee.toObject().as(); if (!builder.writePtr(CalleeToToken(calleeFun, JSOp(*pc) == JSOP_NEW), "CalleeToken")) @@ -1494,7 +1494,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter // | ||||| | // +---------------+ - JitSpew(JitSpew_BaselineBailouts, "Bailing to baseline %s:%u (IonScript=%p) (FrameType=%d)", + JitSpew(JitSpew_BaselineBailouts, "Bailing to baseline %s:%" PRIuSIZE " (IonScript=%p) (FrameType=%d)", iter.script()->filename(), iter.script()->lineno(), (void*) iter.ionScript(), (int) prevFrameType); @@ -1514,7 +1514,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter propagatingExceptionForDebugMode = false; } - JitSpew(JitSpew_BaselineBailouts, " Reading from snapshot offset %u size %u", + JitSpew(JitSpew_BaselineBailouts, " Reading from snapshot offset %u size %" PRIuSIZE, iter.snapshotOffset(), iter.ionScript()->snapshotsListSize()); if (!excInfo) @@ -1540,7 +1540,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter RootedFunction callee(cx, iter.maybeCallee()); RootedScript scr(cx, iter.script()); if (callee) { - JitSpew(JitSpew_BaselineBailouts, " Callee function (%s:%u)", + JitSpew(JitSpew_BaselineBailouts, " Callee function (%s:%" PRIuSIZE ")", scr->filename(), scr->lineno()); } else { JitSpew(JitSpew_BaselineBailouts, " No callee!"); @@ -1575,7 +1575,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter TraceLogStartEvent(logger, TraceLogger_Baseline); } - JitSpew(JitSpew_BaselineBailouts, " FrameNo %d", frameNo); + JitSpew(JitSpew_BaselineBailouts, " FrameNo %" PRIuSIZE, frameNo); // If we are bailing out to a catch or finally block in this frame, // pass excInfo to InitFromBailout and don't unpack any other frames. @@ -1671,7 +1671,7 @@ InvalidateAfterBailout(JSContext* cx, HandleScript outerScript, const char* reas static void HandleBoundsCheckFailure(JSContext* cx, HandleScript outerScript, HandleScript innerScript) { - JitSpew(JitSpew_IonBailouts, "Bounds check failure %s:%d, inlined into %s:%d", + JitSpew(JitSpew_IonBailouts, "Bounds check failure %s:%" PRIuSIZE ", inlined into %s:%" PRIuSIZE, innerScript->filename(), innerScript->lineno(), outerScript->filename(), outerScript->lineno()); @@ -1686,7 +1686,7 @@ HandleBoundsCheckFailure(JSContext* cx, HandleScript outerScript, HandleScript i static void HandleShapeGuardFailure(JSContext* cx, HandleScript outerScript, HandleScript innerScript) { - JitSpew(JitSpew_IonBailouts, "Shape guard failure %s:%d, inlined into %s:%d", + JitSpew(JitSpew_IonBailouts, "Shape guard failure %s:%" PRIuSIZE ", inlined into %s:%" PRIuSIZE, innerScript->filename(), innerScript->lineno(), outerScript->filename(), outerScript->lineno()); @@ -1701,7 +1701,7 @@ HandleShapeGuardFailure(JSContext* cx, HandleScript outerScript, HandleScript in static void HandleBaselineInfoBailout(JSContext* cx, HandleScript outerScript, HandleScript innerScript) { - JitSpew(JitSpew_IonBailouts, "Baseline info failure %s:%d, inlined into %s:%d", + JitSpew(JitSpew_IonBailouts, "Baseline info failure %s:%" PRIuSIZE ", inlined into %s:%" PRIuSIZE, innerScript->filename(), innerScript->lineno(), outerScript->filename(), outerScript->lineno()); @@ -1711,7 +1711,7 @@ HandleBaselineInfoBailout(JSContext* cx, HandleScript outerScript, HandleScript static void HandleLexicalCheckFailure(JSContext* cx, HandleScript outerScript, HandleScript innerScript) { - JitSpew(JitSpew_IonBailouts, "Lexical check failure %s:%d, inlined into %s:%d", + JitSpew(JitSpew_IonBailouts, "Lexical check failure %s:%" PRIuSIZE ", inlined into %s:%" PRIuSIZE, innerScript->filename(), innerScript->lineno(), outerScript->filename(), outerScript->lineno()); @@ -1754,7 +1754,7 @@ CopyFromRematerializedFrame(JSContext* cx, JitActivation* act, uint8_t* fp, size frame->setHasCachedSavedFrame(); JitSpew(JitSpew_BaselineBailouts, - " Copied from rematerialized frame at (%p,%u)", + " Copied from rematerialized frame at (%p,%" PRIuSIZE ")", fp, inlineDepth); // Propagate the debuggee frame flag. For the case where the Debugger did @@ -1891,7 +1891,7 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) } JitSpew(JitSpew_BaselineBailouts, - " Restored outerScript=(%s:%u,%u) innerScript=(%s:%u,%u) (bailoutKind=%u)", + " Restored outerScript=(%s:%" PRIuSIZE ",%u) innerScript=(%s:%" PRIuSIZE ",%u) (bailoutKind=%u)", outerScript->filename(), outerScript->lineno(), outerScript->getWarmUpCount(), innerScript->filename(), innerScript->lineno(), innerScript->getWarmUpCount(), (unsigned) bailoutKind); diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 5c9174655a9a..846a6cd3c816 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -7,6 +7,7 @@ #include "jit/BaselineCompiler.h" #include "mozilla/Casting.h" +#include "mozilla/SizePrintfMacros.h" #include "jit/BaselineIC.h" #include "jit/BaselineJIT.h" @@ -82,10 +83,10 @@ BaselineCompiler::addPCMappingEntry(bool addIndexEntry) MethodStatus BaselineCompiler::compile() { - JitSpew(JitSpew_BaselineScripts, "Baseline compiling script %s:%d (%p)", + JitSpew(JitSpew_BaselineScripts, "Baseline compiling script %s:%" PRIuSIZE " (%p)", script->filename(), script->lineno(), script); - JitSpew(JitSpew_Codegen, "# Emitting baseline code for script %s:%d", + JitSpew(JitSpew_Codegen, "# Emitting baseline code for script %s:%" PRIuSIZE, script->filename(), script->lineno()); TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime()); @@ -217,7 +218,7 @@ BaselineCompiler::compile() baselineScript->setMethod(code); baselineScript->setTemplateEnvironment(templateEnv); - JitSpew(JitSpew_BaselineScripts, "Created BaselineScript %p (raw %p) for %s:%d", + JitSpew(JitSpew_BaselineScripts, "Created BaselineScript %p (raw %p) for %s:%" PRIuSIZE, (void*) baselineScript.get(), (void*) code->raw(), script->filename(), script->lineno()); @@ -279,7 +280,7 @@ BaselineCompiler::compile() // Always register a native => bytecode mapping entry, since profiler can be // turned on with baseline jitcode on stack, and baseline jitcode cannot be invalidated. { - JitSpew(JitSpew_Profiling, "Added JitcodeGlobalEntry for baseline script %s:%d (%p)", + JitSpew(JitSpew_Profiling, "Added JitcodeGlobalEntry for baseline script %s:%" PRIuSIZE " (%p)", script->filename(), script->lineno(), baselineScript.get()); // Generate profiling string. diff --git a/js/src/jit/BaselineDebugModeOSR.cpp b/js/src/jit/BaselineDebugModeOSR.cpp index 889f44dc9b70..8b937ee24591 100644 --- a/js/src/jit/BaselineDebugModeOSR.cpp +++ b/js/src/jit/BaselineDebugModeOSR.cpp @@ -7,6 +7,7 @@ #include "jit/BaselineDebugModeOSR.h" #include "mozilla/DebugOnly.h" +#include "mozilla/SizePrintfMacros.h" #include "jit/BaselineIC.h" #include "jit/JitcodeMap.h" @@ -322,7 +323,7 @@ SpewPatchBaselineFrame(uint8_t* oldReturnAddress, uint8_t* newReturnAddress, JSScript* script, ICEntry::Kind frameKind, jsbytecode* pc) { JitSpew(JitSpew_BaselineDebugModeOSR, - "Patch return %p -> %p on BaselineJS frame (%s:%d) from %s at %s", + "Patch return %p -> %p on BaselineJS frame (%s:%" PRIuSIZE ") from %s at %s", oldReturnAddress, newReturnAddress, script->filename(), script->lineno(), ICEntryKindToString(frameKind), CodeName[(JSOp)*pc]); } @@ -332,7 +333,7 @@ SpewPatchBaselineFrameFromExceptionHandler(uint8_t* oldReturnAddress, uint8_t* n JSScript* script, jsbytecode* pc) { JitSpew(JitSpew_BaselineDebugModeOSR, - "Patch return %p -> %p on BaselineJS frame (%s:%d) from exception handler at %s", + "Patch return %p -> %p on BaselineJS frame (%s:%" PRIuSIZE ") from exception handler at %s", oldReturnAddress, newReturnAddress, script->filename(), script->lineno(), CodeName[(JSOp)*pc]); } @@ -667,7 +668,7 @@ RecompileBaselineScriptForDebugMode(JSContext* cx, JSScript* script, if (oldBaselineScript->hasDebugInstrumentation() == observing) return true; - JitSpew(JitSpew_BaselineDebugModeOSR, "Recompiling (%s:%d) for %s", + JitSpew(JitSpew_BaselineDebugModeOSR, "Recompiling (%s:%" PRIuSIZE ") for %s", script->filename(), script->lineno(), observing ? "DEBUGGING" : "NORMAL EXECUTION"); script->setBaselineScript(cx->runtime(), nullptr); diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 5835283268d4..4f43c18989d0 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -2586,7 +2586,7 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_ { JitSpew(JitSpew_BaselineIC, " Generating SetElem_DenseOrUnboxedArrayAdd stub " - "(shape=%p, group=%p, protoDepth=%u)", + "(shape=%p, group=%p, protoDepth=%" PRIuSIZE ")", shape.get(), group.get(), protoDepth); ICSetElemDenseOrUnboxedArrayAddCompiler compiler(cx, obj, protoDepth); ICUpdatedStub* newStub = compiler.getStub(compiler.getStubSpace(outerScript)); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index ff10782acef0..9e55d5bb42e3 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -9244,7 +9244,7 @@ CodeGenerator::generateWasm(wasm::SigIdDesc sigId, wasm::TrapOffset trapOffset, bool CodeGenerator::generate() { - JitSpew(JitSpew_Codegen, "# Emitting code for script %s:%d", + JitSpew(JitSpew_Codegen, "# Emitting code for script %s:%" PRIuSIZE, gen->info().script()->filename(), gen->info().script()->lineno()); diff --git a/js/src/jit/FlowAliasAnalysis.cpp b/js/src/jit/FlowAliasAnalysis.cpp index e237163bb7f8..2b88e36785af 100644 --- a/js/src/jit/FlowAliasAnalysis.cpp +++ b/js/src/jit/FlowAliasAnalysis.cpp @@ -402,7 +402,7 @@ DumpImprovement(MDefinition *load, MDefinitionVector& input, MDefinitionVector& if (JitSpewEnabled(JitSpew_Alias)) { Fprinter &print = JitSpewPrinter(); JitSpewHeader(JitSpew_Alias); - print.printf(" Improve dependency from ", load->id()); + print.printf(" Improve dependency from %d", load->id()); DumpStoreList(input); print.printf(" to "); DumpStoreList(output); diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 945947e77308..cacd6e181e7a 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -6,6 +6,7 @@ #include "jit/Ion.h" +#include "mozilla/IntegerPrintfMacros.h" #include "mozilla/MemoryReporting.h" #include "mozilla/SizePrintfMacros.h" #include "mozilla/ThreadLocal.h" @@ -2136,7 +2137,7 @@ TrackIonAbort(JSContext* cx, JSScript* script, jsbytecode* pc, const char* messa static void TrackAndSpewIonAbort(JSContext* cx, JSScript* script, const char* message) { - JitSpew(JitSpew_IonAbort, message); + JitSpew(JitSpew_IonAbort, "%s", message); TrackIonAbort(cx, script, script->code(), message); } @@ -2395,7 +2396,7 @@ CheckScriptSize(JSContext* cx, JSScript* script) numLocalsAndArgs > MAX_MAIN_THREAD_LOCALS_AND_ARGS) { if (!OffThreadCompilationAvailable(cx)) { - JitSpew(JitSpew_IonAbort, "Script too large (%u bytes) (%u locals/args)", + JitSpew(JitSpew_IonAbort, "Script too large (%" PRIuSIZE " bytes) (%u locals/args)", script->length(), numLocalsAndArgs); TrackIonAbort(cx, script, script->code(), "too large"); return Method_CantCompile; @@ -3012,7 +3013,7 @@ InvalidateActivation(FreeOp* fop, const JitActivationIterator& activations, bool #ifdef JS_JITSPEW switch (it.type()) { case JitFrame_Exit: - JitSpew(JitSpew_IonInvalidate, "#%d exit frame @ %p", frameno, it.fp()); + JitSpew(JitSpew_IonInvalidate, "#%" PRIuSIZE " exit frame @ %p", frameno, it.fp()); break; case JitFrame_BaselineJS: case JitFrame_IonJS: @@ -3027,26 +3028,26 @@ InvalidateActivation(FreeOp* fop, const JitActivationIterator& activations, bool else if (it.isBailoutJS()) type = "Bailing"; JitSpew(JitSpew_IonInvalidate, - "#%d %s JS frame @ %p, %s:%" PRIuSIZE " (fun: %p, script: %p, pc %p)", + "#%" PRIuSIZE " %s JS frame @ %p, %s:%" PRIuSIZE " (fun: %p, script: %p, pc %p)", frameno, type, it.fp(), it.script()->maybeForwardedFilename(), it.script()->lineno(), it.maybeCallee(), (JSScript*)it.script(), it.returnAddressToFp()); break; } case JitFrame_IonStub: - JitSpew(JitSpew_IonInvalidate, "#%d ion stub frame @ %p", frameno, it.fp()); + JitSpew(JitSpew_IonInvalidate, "#%" PRIuSIZE " ion stub frame @ %p", frameno, it.fp()); break; case JitFrame_BaselineStub: - JitSpew(JitSpew_IonInvalidate, "#%d baseline stub frame @ %p", frameno, it.fp()); + JitSpew(JitSpew_IonInvalidate, "#%" PRIuSIZE " baseline stub frame @ %p", frameno, it.fp()); break; case JitFrame_Rectifier: - JitSpew(JitSpew_IonInvalidate, "#%d rectifier frame @ %p", frameno, it.fp()); + JitSpew(JitSpew_IonInvalidate, "#%" PRIuSIZE " rectifier frame @ %p", frameno, it.fp()); break; case JitFrame_IonAccessorIC: - JitSpew(JitSpew_IonInvalidate, "#%d ion IC getter/setter frame @ %p", frameno, it.fp()); + JitSpew(JitSpew_IonInvalidate, "#%" PRIuSIZE " ion IC getter/setter frame @ %p", frameno, it.fp()); break; case JitFrame_Entry: - JitSpew(JitSpew_IonInvalidate, "#%d entry frame @ %p", frameno, it.fp()); + JitSpew(JitSpew_IonInvalidate, "#%" PRIuSIZE " entry frame @ %p", frameno, it.fp()); break; } #endif // JS_JITSPEW @@ -3141,7 +3142,7 @@ InvalidateActivation(FreeOp* fop, const JitActivationIterator& activations, bool CodeLocationLabel osiPatchPoint = SafepointReader::InvalidationPatchPoint(ionScript, si); CodeLocationLabel invalidateEpilogue(ionCode, CodeOffset(ionScript->invalidateEpilogueOffset())); - JitSpew(JitSpew_IonInvalidate, " ! Invalidate ionScript %p (inv count %u) -> patching osipoint %p", + JitSpew(JitSpew_IonInvalidate, " ! Invalidate ionScript %p (inv count %" PRIuSIZE ") -> patching osipoint %p", ionScript, ionScript->invalidationCount(), (void*) osiPatchPoint.raw()); Assembler::PatchWrite_NearCall(osiPatchPoint, invalidateEpilogue); } @@ -3358,7 +3359,7 @@ AutoFlushICache::setRange(uintptr_t start, size_t len) AutoFlushICache* afc = TlsPerThreadData.get()->PerThreadData::autoFlushICache(); MOZ_ASSERT(afc); MOZ_ASSERT(!afc->start_); - JitSpewCont(JitSpew_CacheFlush, "(%x %x):", start, len); + JitSpewCont(JitSpew_CacheFlush, "(%" PRIxPTR " %" PRIxSIZE "):", start, len); uintptr_t stop = start + len; afc->start_ = start; diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 5a2d7b14d717..ffb7a6877332 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -6,6 +6,8 @@ #include "jit/IonAnalysis.h" +#include "mozilla/SizePrintfMacros.h" + #include "jit/AliasAnalysis.h" #include "jit/BaselineInspector.h" #include "jit/BaselineJIT.h" @@ -445,9 +447,10 @@ jit::PruneUnusedBranches(MIRGenerator* mir, MIRGraph& graph) shouldBailout = false; JitSpew(JitSpew_Prune, "info: block %d," - " predCount: %lu, domInst: %lu, span: %lu, effectful: %lu, " - " isLoopExit: %s, numSuccessorsOfPred: %lu." - " (score: %lu, shouldBailout: %s)", + " predCount: %" PRIuSIZE ", domInst: %" PRIuSIZE + ", span: %" PRIuSIZE ", effectful: %" PRIuSIZE ", " + " isLoopExit: %s, numSuccessorsOfPred: %" PRIuSIZE "." + " (score: %" PRIuSIZE ", shouldBailout: %s)", block->id(), predCount, numDominatedInst, branchSpan, numEffectfulInst, isLoopExit ? "true" : "false", numSuccessorsOfPreds, score, shouldBailout ? "true" : "false"); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 42797a84c8bd..868d9e8e497f 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -229,7 +229,7 @@ class IonBuilder MOZ_MUST_USE bool inspectOpcode(JSOp op); uint32_t readIndex(jsbytecode* pc); JSAtom* readAtom(jsbytecode* pc); - bool abort(const char* message, ...); + bool abort(const char* message, ...) MOZ_FORMAT_PRINTF(2, 3); void trackActionableAbort(const char* message); void spew(const char* message); diff --git a/js/src/jit/JSONSpewer.cpp b/js/src/jit/JSONSpewer.cpp index d6105f498bab..330b419f5774 100644 --- a/js/src/jit/JSONSpewer.cpp +++ b/js/src/jit/JSONSpewer.cpp @@ -8,6 +8,8 @@ #include "jit/JSONSpewer.h" +#include "mozilla/SizePrintfMacros.h" + #include #include "jit/BacktrackingAllocator.h" @@ -146,7 +148,7 @@ JSONSpewer::beginFunction(JSScript* script) { beginObject(); if (script) - stringProperty("name", "%s:%d", script->filename(), script->lineno()); + stringProperty("name", "%s:%" PRIuSIZE, script->filename(), script->lineno()); else stringProperty("name", "asm.js compilation"); beginListProperty("passes"); @@ -156,7 +158,7 @@ void JSONSpewer::beginPass(const char* pass) { beginObject(); - stringProperty("name", pass); + stringProperty("name", "%s", pass); } void diff --git a/js/src/jit/JSONSpewer.h b/js/src/jit/JSONSpewer.h index f4172c6b46ed..02f449c7ab04 100644 --- a/js/src/jit/JSONSpewer.h +++ b/js/src/jit/JSONSpewer.h @@ -36,8 +36,8 @@ class JSONSpewer void beginObject(); void beginObjectProperty(const char* name); void beginListProperty(const char* name); - void stringValue(const char* format, ...); - void stringProperty(const char* name, const char* format, ...); + void stringValue(const char* format, ...) MOZ_FORMAT_PRINTF(2, 3); + void stringProperty(const char* name, const char* format, ...) MOZ_FORMAT_PRINTF(3, 4); void beginStringProperty(const char* name); void endStringProperty(); void integerValue(int value); diff --git a/js/src/jit/JitSpewer.h b/js/src/jit/JitSpewer.h index 024e7d5a1ff8..a44eec4662f9 100644 --- a/js/src/jit/JitSpewer.h +++ b/js/src/jit/JitSpewer.h @@ -172,9 +172,9 @@ class JitSpewIndent ~JitSpewIndent(); }; -void JitSpew(JitSpewChannel channel, const char* fmt, ...); -void JitSpewStart(JitSpewChannel channel, const char* fmt, ...); -void JitSpewCont(JitSpewChannel channel, const char* fmt, ...); +void JitSpew(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3); +void JitSpewStart(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3); +void JitSpewCont(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3); void JitSpewFin(JitSpewChannel channel); void JitSpewHeader(JitSpewChannel channel); bool JitSpewEnabled(JitSpewChannel channel); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index c8c11110d4c8..02ef4ac9b78d 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -5162,7 +5162,7 @@ void MStoreSlot::printOpcode(GenericPrinter& out) const { PrintOpcodeName(out, op()); - out.printf(" ", slot()); + out.printf(" "); getOperand(0)->printName(out); out.printf(" %d ", slot()); getOperand(1)->printName(out); diff --git a/js/src/jit/MIRGenerator.h b/js/src/jit/MIRGenerator.h index 2aedc1a924a6..342ff2945431 100644 --- a/js/src/jit/MIRGenerator.h +++ b/js/src/jit/MIRGenerator.h @@ -72,7 +72,7 @@ class MIRGenerator // Set an error state and prints a message. Returns false so errors can be // propagated up. - bool abort(const char* message, ...); // always returns false + bool abort(const char* message, ...) MOZ_FORMAT_PRINTF(2, 3); // always returns false bool abortFmt(const char* message, va_list ap); // always returns false bool errored() const { diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp index 029b3c082be1..103ee4516113 100644 --- a/js/src/jit/OptimizationTracking.cpp +++ b/js/src/jit/OptimizationTracking.cpp @@ -326,7 +326,7 @@ UniqueTrackedOptimizations::sortByFrequency(JSContext* cx) MOZ_ASSERT(p); p->value().index = sorted_.length(); - JitSpew(JitSpew_OptimizationTracking, " Entry %u has frequency %u", + JitSpew(JitSpew_OptimizationTracking, " Entry %" PRIuSIZE " has frequency %" PRIu32, sorted_.length(), p->value().frequency); if (!sorted_.append(entries[i])) @@ -765,14 +765,14 @@ IonTrackedOptimizationsRegion::WriteRun(CompactBufferWriter& writer, const UniqueTrackedOptimizations& unique) { // Write the header, which is the range that this whole run encompasses. - JitSpew(JitSpew_OptimizationTracking, " Header: [%u, %u]", + JitSpew(JitSpew_OptimizationTracking, " Header: [%" PRIuSIZE ", %" PRIuSIZE "]", start->startOffset.offset(), (end - 1)->endOffset.offset()); writer.writeUnsigned(start->startOffset.offset()); writer.writeUnsigned((end - 1)->endOffset.offset()); // Write the first entry of the run, which is not delta-encoded. JitSpew(JitSpew_OptimizationTracking, - " [%6u, %6u] vector %3u, offset %4u", + " [%6" PRIuSIZE ", %6" PRIuSIZE "] vector %3u, offset %4" PRIuSIZE, start->startOffset.offset(), start->endOffset.offset(), unique.indexOf(start->optimizations), writer.length()); uint32_t prevEndOffset = start->endOffset.offset(); @@ -789,7 +789,7 @@ IonTrackedOptimizationsRegion::WriteRun(CompactBufferWriter& writer, uint8_t index = unique.indexOf(entry->optimizations); JitSpew(JitSpew_OptimizationTracking, - " [%6u, %6u] delta [+%5u, +%5u] vector %3u, offset %4u", + " [%6u, %6u] delta [+%5u, +%5u] vector %3u, offset %4" PRIuSIZE, startOffset, endOffset, startDelta, length, index, writer.length()); WriteDelta(writer, startDelta, length, index); @@ -825,7 +825,7 @@ WriteOffsetsTable(CompactBufferWriter& writer, const Vector& offse // Write entry offset table. for (size_t i = 0; i < offsets.length(); i++) { - JitSpew(JitSpew_OptimizationTracking, " Entry %u reverse offset %u", + JitSpew(JitSpew_OptimizationTracking, " Entry %" PRIuSIZE " reverse offset %u", i, tableOffset - padding - offsets[i]); writer.writeNativeEndianUint32_t(tableOffset - padding - offsets[i]); } @@ -885,7 +885,7 @@ SpewConstructor(TypeSet::Type ty, JSFunction* constructor) Maybe lineno; InterpretedFunctionFilenameAndLineNumber(constructor, &filename, &lineno); - JitSpew(JitSpew_OptimizationTracking, " Unique type %s has constructor %s (%s:%" PRIuSIZE ")", + JitSpew(JitSpew_OptimizationTracking, " Unique type %s has constructor %s (%s:%u)", TypeSet::TypeString(ty), buf, filename, lineno.isSome() ? *lineno : 0); #endif } @@ -919,7 +919,7 @@ jit::WriteIonTrackedOptimizationsTable(JSContext* cx, CompactBufferWriter& write if (JitSpewEnabled(JitSpew_OptimizationTracking)) { JitSpewStart(JitSpew_OptimizationTracking, "=> Training data: "); for (const NativeToTrackedOptimizations* entry = start; entry != end; entry++) { - JitSpewCont(JitSpew_OptimizationTracking, "%u,%u,%u ", + JitSpewCont(JitSpew_OptimizationTracking, "%" PRIuSIZE ",%" PRIuSIZE ",%u ", entry->startOffset.offset(), entry->endOffset.offset(), unique.indexOf(entry->optimizations)); } @@ -934,7 +934,8 @@ jit::WriteIonTrackedOptimizationsTable(JSContext* cx, CompactBufferWriter& write JitSpew(JitSpew_Profiling, "=> Writing regions"); while (entry != end) { uint32_t runLength = IonTrackedOptimizationsRegion::ExpectedRunLength(entry, end); - JitSpew(JitSpew_OptimizationTracking, " Run at entry %u, length %u, offset %u", + JitSpew(JitSpew_OptimizationTracking, + " Run at entry %" PRIuSIZE ", length %" PRIu32 ", offset %" PRIuSIZE, entry - start, runLength, writer.length()); if (!offsets.append(writer.length())) @@ -957,7 +958,7 @@ jit::WriteIonTrackedOptimizationsTable(JSContext* cx, CompactBufferWriter& write offsets.clear(); const UniqueTrackedOptimizations::SortedVector& vec = unique.sortedVector(); - JitSpew(JitSpew_OptimizationTracking, "=> Writing unique optimizations table with %u entr%s", + JitSpew(JitSpew_OptimizationTracking, "=> Writing unique optimizations table with %" PRIuSIZE " entr%s", vec.length(), vec.length() == 1 ? "y" : "ies"); // Write out type info payloads. @@ -967,7 +968,8 @@ jit::WriteIonTrackedOptimizationsTable(JSContext* cx, CompactBufferWriter& write for (const UniqueTrackedOptimizations::SortEntry* p = vec.begin(); p != vec.end(); p++) { const TempOptimizationTypeInfoVector* v = p->types; - JitSpew(JitSpew_OptimizationTracking, " Type info entry %u of length %u, offset %u", + JitSpew(JitSpew_OptimizationTracking, + " Type info entry %" PRIuSIZE " of length %" PRIuSIZE ", offset %" PRIuSIZE, p - vec.begin(), v->length(), writer.length()); SpewTempOptimizationTypeInfoVector(v, " "); @@ -1017,7 +1019,8 @@ jit::WriteIonTrackedOptimizationsTable(JSContext* cx, CompactBufferWriter& write // Write out attempts payloads. for (const UniqueTrackedOptimizations::SortEntry* p = vec.begin(); p != vec.end(); p++) { const TempOptimizationAttemptsVector* v = p->attempts; - JitSpew(JitSpew_OptimizationTracking, " Attempts entry %u of length %u, offset %u", + JitSpew(JitSpew_OptimizationTracking, + " Attempts entry %" PRIuSIZE " of length %" PRIuSIZE ", offset %" PRIuSIZE, p - vec.begin(), v->length(), writer.length()); SpewTempOptimizationAttemptsVector(v, " "); diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp index 57577160544f..57d5d18a465b 100644 --- a/js/src/jit/Recover.cpp +++ b/js/src/jit/Recover.cpp @@ -6,6 +6,8 @@ #include "jit/Recover.h" +#include "mozilla/SizePrintfMacros.h" + #include "jsapi.h" #include "jscntxt.h" #include "jsmath.h" @@ -123,7 +125,7 @@ MResumePoint::writeRecoverData(CompactBufferWriter& writer) const uint32_t formalArgs = CountArgSlots(script, fun); uint32_t nallocs = formalArgs + script->nfixed() + exprStack; - JitSpew(JitSpew_IonSnapshots, "Starting frame; implicit %u, formals %u, fixed %u, exprs %u", + JitSpew(JitSpew_IonSnapshots, "Starting frame; implicit %u, formals %u, fixed %" PRIuSIZE ", exprs %u", implicit, formalArgs - implicit, script->nfixed(), exprStack); uint32_t pcoff = script->pcToOffset(pc()); diff --git a/js/src/jit/Safepoints.cpp b/js/src/jit/Safepoints.cpp index c775c7d131c0..b0bb530f9933 100644 --- a/js/src/jit/Safepoints.cpp +++ b/js/src/jit/Safepoints.cpp @@ -7,6 +7,7 @@ #include "jit/Safepoints.h" #include "mozilla/MathAlgorithms.h" +#include "mozilla/SizePrintfMacros.h" #include "jit/BitSet.h" #include "jit/JitSpewer.h" @@ -31,7 +32,7 @@ SafepointWriter::init(TempAllocator& alloc) uint32_t SafepointWriter::startEntry() { - JitSpew(JitSpew_Safepoints, "Encoding safepoint (position %d):", stream_.length()); + JitSpew(JitSpew_Safepoints, "Encoding safepoint (position %" PRIuSIZE "):", stream_.length()); return uint32_t(stream_.length()); } diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp index 1c227439e349..177f5e8e394e 100644 --- a/js/src/jit/SharedIC.cpp +++ b/js/src/jit/SharedIC.cpp @@ -2132,7 +2132,7 @@ UpdateExistingGenerationalDOMProxyStub(ICGetProp_Fallback* stub, // Update generation uint64_t generation = expandoAndGeneration->generation; JitSpew(JitSpew_BaselineIC, - " Updating existing stub with generation, old value: %i, " + " Updating existing stub with generation, old value: %" PRIu64 ", " "new value: %" PRIu64 "", updateStub->generation(), generation); updateStub->setGeneration(generation); diff --git a/js/src/jit/SharedIC.h b/js/src/jit/SharedIC.h index b8e081688897..42198c89096f 100644 --- a/js/src/jit/SharedIC.h +++ b/js/src/jit/SharedIC.h @@ -202,8 +202,10 @@ class ICFallbackStub; #undef FORWARD_DECLARE_STUBS #ifdef JS_JITSPEW -void FallbackICSpew(JSContext* cx, ICFallbackStub* stub, const char* fmt, ...); -void TypeFallbackICSpew(JSContext* cx, ICTypeMonitor_Fallback* stub, const char* fmt, ...); +void FallbackICSpew(JSContext* cx, ICFallbackStub* stub, const char* fmt, ...) + MOZ_FORMAT_PRINTF(3, 4); +void TypeFallbackICSpew(JSContext* cx, ICTypeMonitor_Fallback* stub, const char* fmt, ...) + MOZ_FORMAT_PRINTF(3, 4); #else #define FallbackICSpew(...) #define TypeFallbackICSpew(...) diff --git a/js/src/jit/ValueNumbering.cpp b/js/src/jit/ValueNumbering.cpp index 2335e5f2044d..5a3115646729 100644 --- a/js/src/jit/ValueNumbering.cpp +++ b/js/src/jit/ValueNumbering.cpp @@ -1002,7 +1002,7 @@ ValueNumberer::visitBlock(MBasicBlock* block, const MBasicBlock* dominatorRoot) bool ValueNumberer::visitDominatorTree(MBasicBlock* dominatorRoot) { - JitSpew(JitSpew_GVN, " Visiting dominator tree (with %llu blocks) rooted at block%u%s", + JitSpew(JitSpew_GVN, " Visiting dominator tree (with %" PRIu64 " blocks) rooted at block%u%s", uint64_t(dominatorRoot->numDominated()), dominatorRoot->id(), dominatorRoot == graph_.entryBlock() ? " (normal entry block)" : dominatorRoot == graph_.osrBlock() ? " (OSR entry block)" : @@ -1228,7 +1228,7 @@ ValueNumberer::run(UpdateAliasAnalysisFlag updateAliasAnalysis) { updateAliasAnalysis_ = updateAliasAnalysis == UpdateAliasAnalysis; - JitSpew(JitSpew_GVN, "Running GVN on graph (with %llu blocks)", + JitSpew(JitSpew_GVN, "Running GVN on graph (with %" PRIu64 " blocks)", uint64_t(graph_.numBlocks())); // Adding fixup blocks only make sense iff we have a second entry point into @@ -1288,7 +1288,7 @@ ValueNumberer::run(UpdateAliasAnalysisFlag updateAliasAnalysis) break; } - JitSpew(JitSpew_GVN, "Re-running GVN on graph (run %d, now with %llu blocks)", + JitSpew(JitSpew_GVN, "Re-running GVN on graph (run %d, now with %" PRIu64 " blocks)", runs, uint64_t(graph_.numBlocks())); } diff --git a/js/src/jit/arm/Assembler-arm.h b/js/src/jit/arm/Assembler-arm.h index 455a3e828515..04813096c044 100644 --- a/js/src/jit/arm/Assembler-arm.h +++ b/js/src/jit/arm/Assembler-arm.h @@ -1363,7 +1363,7 @@ class Assembler : public AssemblerShared uint32_t spewResolve(Label* l); uint32_t spewProbe(Label* l); uint32_t spewDefine(Label* l); - void spew(const char* fmt, ...); + void spew(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3); void spew(const char* fmt, va_list args); #endif diff --git a/js/src/jit/arm/disasm/Disasm-arm.cpp b/js/src/jit/arm/disasm/Disasm-arm.cpp index 1e0cb389387b..8bd7bff0c283 100644 --- a/js/src/jit/arm/disasm/Disasm-arm.cpp +++ b/js/src/jit/arm/disasm/Disasm-arm.cpp @@ -43,6 +43,7 @@ namespace disasm { // Helper function for printing to a Vector. static int +MOZ_FORMAT_PRINTF(2, 3) SNPrintF(V8Vector str, const char* format, ...) { va_list args; diff --git a/js/src/jit/shared/CodeGenerator-shared.cpp b/js/src/jit/shared/CodeGenerator-shared.cpp index 30c638edc375..f69cb7449196 100644 --- a/js/src/jit/shared/CodeGenerator-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-shared.cpp @@ -7,6 +7,7 @@ #include "jit/shared/CodeGenerator-shared-inl.h" #include "mozilla/DebugOnly.h" +#include "mozilla/SizePrintfMacros.h" #include "jit/CompactBuffer.h" #include "jit/IonCaches.h" @@ -233,7 +234,7 @@ CodeGeneratorShared::addNativeToBytecodeEntry(const BytecodeSite* site) // bytecodeOffset, but the nativeOffset has changed, do nothing. // The same site just generated some more code. if (lastEntry.tree == tree && lastEntry.pc == pc) { - JitSpew(JitSpew_Profiling, " => In-place update [%u-%u]", + JitSpew(JitSpew_Profiling, " => In-place update [%" PRIuSIZE "-%" PRIu32 "]", lastEntry.nativeOffset.offset(), nativeOffset); return true; } @@ -280,7 +281,7 @@ CodeGeneratorShared::dumpNativeToBytecodeEntries() { #ifdef JS_JITSPEW InlineScriptTree* topTree = gen->info().inlineScriptTree(); - JitSpewStart(JitSpew_Profiling, "Native To Bytecode Entries for %s:%d\n", + JitSpewStart(JitSpew_Profiling, "Native To Bytecode Entries for %s:%" PRIuSIZE "\n", topTree->script()->filename(), topTree->script()->lineno()); for (unsigned i = 0; i < nativeToBytecodeList_.length(); i++) dumpNativeToBytecodeEntry(i); @@ -303,16 +304,16 @@ CodeGeneratorShared::dumpNativeToBytecodeEntry(uint32_t idx) if (nextRef->tree == ref.tree) pcDelta = nextRef->pc - ref.pc; } - JitSpewStart(JitSpew_Profiling, " %08x [+%-6d] => %-6d [%-4d] {%-10s} (%s:%d", + JitSpewStart(JitSpew_Profiling, " %08" PRIxSIZE " [+%-6d] => %-6ld [%-4d] {%-10s} (%s:%" PRIuSIZE, ref.nativeOffset.offset(), nativeDelta, - ref.pc - script->code(), + (long) (ref.pc - script->code()), pcDelta, CodeName[JSOp(*ref.pc)], script->filename(), script->lineno()); for (tree = tree->caller(); tree; tree = tree->caller()) { - JitSpewCont(JitSpew_Profiling, " <= %s:%d", tree->script()->filename(), + JitSpewCont(JitSpew_Profiling, " <= %s:%" PRIuSIZE, tree->script()->filename(), tree->script()->lineno()); } JitSpewCont(JitSpew_Profiling, ")"); @@ -927,7 +928,7 @@ CodeGeneratorShared::generateCompactTrackedOptimizationsMap(JSContext* cx, JitCo "== Compact Native To Optimizations Map [%p-%p] size %u", data, data + trackedOptimizationsMapSize_, trackedOptimizationsMapSize_); JitSpew(JitSpew_OptimizationTracking, - " with type list of length %u, size %u", + " with type list of length %" PRIuSIZE ", size %" PRIuSIZE, allTypes->length(), allTypes->length() * sizeof(IonTrackedTypeWithAddendum)); return true; diff --git a/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h b/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h index c6783c61950a..74fa60b12402 100644 --- a/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h +++ b/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h @@ -8,6 +8,7 @@ #define jit_shared_IonAssemblerBufferWithConstantPools_h #include "mozilla/MathAlgorithms.h" +#include "mozilla/SizePrintfMacros.h" #include @@ -792,7 +793,7 @@ struct AssemblerBufferWithConstantPools : public AssemblerBuffer + +#include "jsprf.h" + +#include "jsapi-tests/tests.h" + +static bool +MOZ_FORMAT_PRINTF(2, 3) +print_one (const char *expect, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + char *output = JS_vsmprintf (fmt, ap); + va_end(ap); + + bool result = output && !strcmp(output, expect); + JS_smprintf_free(output); + + return result; +} + +static const char * +zero() +{ + return nullptr; +} + +BEGIN_TEST(testPrintf) +{ + CHECK(print_one("23", "%d", 23)); + CHECK(print_one("-1", "%d", -1)); + CHECK(print_one("23", "%u", 23u)); + CHECK(print_one("0x17", "0x%x", 23u)); + CHECK(print_one("0xFF", "0x%X", 255u)); + CHECK(print_one("027", "0%o", 23u)); + CHECK(print_one("-1", "%hd", (short) -1)); + // This could be expanded if need be, it's just convenient to do + // it this way. + if (sizeof(short) == 2) { + CHECK(print_one("8000", "%hx", (unsigned short) 0x8000)); + } + CHECK(print_one("0xf0f0", "0x%lx", 0xf0f0ul)); + CHECK(print_one("0xF0F0", "0x%llX", 0xf0f0ull)); + CHECK(print_one("27270", "%zu", (size_t) 27270)); + CHECK(print_one("27270", "%" PRIuSIZE, (size_t) 27270)); + CHECK(print_one("hello", "he%so", "ll")); + CHECK(print_one("(null)", "%s", zero())); + CHECK(print_one("0", "%p", (char *) 0)); + CHECK(print_one("h", "%c", 'h')); + CHECK(print_one("1.500000", "%f", 1.5f)); + CHECK(print_one("1.5", "%g", 1.5)); + + CHECK(print_one("2727", "%" PRIu32, (uint32_t) 2727)); + CHECK(print_one("aa7", "%" PRIx32, (uint32_t) 2727)); + CHECK(print_one("2727", "%" PRIu64, (uint64_t) 2727)); + CHECK(print_one("aa7", "%" PRIx64, (uint64_t) 2727)); + + return true; +} +END_TEST(testPrintf) diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 9dc247562fbf..fcf94fea486f 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -5199,13 +5199,16 @@ const uint16_t MaxNumErrorArguments = 10; * and its arguments. */ extern JS_PUBLIC_API(void) -JS_ReportErrorASCII(JSContext* cx, const char* format, ...); +JS_ReportErrorASCII(JSContext* cx, const char* format, ...) + MOZ_FORMAT_PRINTF(2, 3); extern JS_PUBLIC_API(void) -JS_ReportErrorLatin1(JSContext* cx, const char* format, ...); +JS_ReportErrorLatin1(JSContext* cx, const char* format, ...) + MOZ_FORMAT_PRINTF(2, 3); extern JS_PUBLIC_API(void) -JS_ReportErrorUTF8(JSContext* cx, const char* format, ...); +JS_ReportErrorUTF8(JSContext* cx, const char* format, ...) + MOZ_FORMAT_PRINTF(2, 3); /* * Use an errorNumber to retrieve the format string, args are char* @@ -5257,13 +5260,16 @@ JS_ReportErrorNumberUCArray(JSContext* cx, JSErrorCallback errorCallback, * being set, false otherwise. */ extern JS_PUBLIC_API(bool) -JS_ReportWarningASCII(JSContext* cx, const char* format, ...); +JS_ReportWarningASCII(JSContext* cx, const char* format, ...) + MOZ_FORMAT_PRINTF(2, 3); extern JS_PUBLIC_API(bool) -JS_ReportWarningLatin1(JSContext* cx, const char* format, ...); +JS_ReportWarningLatin1(JSContext* cx, const char* format, ...) + MOZ_FORMAT_PRINTF(2, 3); extern JS_PUBLIC_API(bool) -JS_ReportWarningUTF8(JSContext* cx, const char* format, ...); +JS_ReportWarningUTF8(JSContext* cx, const char* format, ...) + MOZ_FORMAT_PRINTF(2, 3); extern JS_PUBLIC_API(bool) JS_ReportErrorFlagsAndNumberASCII(JSContext* cx, unsigned flags, diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 061afb85aefa..83a83b3f637c 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -763,11 +763,16 @@ FormatValue(JSContext* cx, const Value& vArg, JSAutoByteString& bytes) // Wrapper for JS_sprintf_append() that reports allocation failure to the // context. -template static char* -sprintf_append(JSContext* cx, char* buf, Args&&... args) +MOZ_FORMAT_PRINTF(3, 4) +sprintf_append(JSContext* cx, char* buf, const char* fmt, ...) { - char* result = JS_sprintf_append(buf, mozilla::Forward(args)...); + va_list ap; + + va_start(ap, fmt); + char* result = JS_vsprintf_append(buf, fmt, ap); + va_end(ap); + if (!result) { ReportOutOfMemory(cx); return nullptr; diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 94be4fccd103..27321c2034c1 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3630,11 +3630,11 @@ js::DumpBacktrace(JSContext* cx, FILE* fp) i.isWasm() ? 'W' : '?'; - sprinter.printf("#%d %14p %c %s:%d", + sprinter.printf("#%" PRIuSIZE " %14p %c %s:%d", depth, i.rawFramePtr(), frameType, filename, line); if (i.hasScript()) { - sprinter.printf(" (%p @ %d)\n", + sprinter.printf(" (%p @ %" PRIuSIZE ")\n", i.script(), i.script()->pcToOffset(i.pc())); } else { sprinter.printf(" (%p)\n", i.pc()); diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index a492b36831fa..ff340275806e 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -151,14 +151,14 @@ const char * PCCounts::numExecName = "interp"; static MOZ_MUST_USE bool DumpIonScriptCounts(Sprinter* sp, HandleScript script, jit::IonScriptCounts* ionCounts) { - if (!sp->jsprintf("IonScript [%lu blocks]:\n", ionCounts->numBlocks())) + if (!sp->jsprintf("IonScript [%" PRIuSIZE " blocks]:\n", ionCounts->numBlocks())) return false; for (size_t i = 0; i < ionCounts->numBlocks(); i++) { const jit::IonBlockCounts& block = ionCounts->block(i); unsigned lineNumber = 0, columnNumber = 0; lineNumber = PCToLineNumber(script, script->offsetToPC(block.offset()), &columnNumber); - if (!sp->jsprintf("BB #%lu [%05u,%u,%u]", + if (!sp->jsprintf("BB #%" PRIu32 " [%05u,%u,%u]", block.id(), block.offset(), lineNumber, columnNumber)) { return false; @@ -168,10 +168,10 @@ DumpIonScriptCounts(Sprinter* sp, HandleScript script, jit::IonScriptCounts* ion return false; } for (size_t j = 0; j < block.numSuccessors(); j++) { - if (!sp->jsprintf(" -> #%lu", block.successor(j))) + if (!sp->jsprintf(" -> #%" PRIu32, block.successor(j))) return false; } - if (!sp->jsprintf(" :: %llu hits\n", block.hitCount())) + if (!sp->jsprintf(" :: %" PRIu64 " hits\n", block.hitCount())) return false; if (!sp->jsprintf("%s\n", block.code())) return false; diff --git a/js/src/jsprf.cpp b/js/src/jsprf.cpp index 1f8c1a6dffc3..646b938de834 100644 --- a/js/src/jsprf.cpp +++ b/js/src/jsprf.cpp @@ -63,18 +63,18 @@ struct NumArgState typedef mozilla::Vector NumArgStateVector; -#define TYPE_INT16 0 -#define TYPE_UINT16 1 +#define TYPE_SHORT 0 +#define TYPE_USHORT 1 #define TYPE_INTN 2 #define TYPE_UINTN 3 -#define TYPE_INT32 4 -#define TYPE_UINT32 5 -#define TYPE_INT64 6 -#define TYPE_UINT64 7 +#define TYPE_LONG 4 +#define TYPE_ULONG 5 +#define TYPE_LONGLONG 6 +#define TYPE_ULONGLONG 7 #define TYPE_STRING 8 #define TYPE_DOUBLE 9 #define TYPE_INTSTR 10 -#define TYPE_WSTRING 11 +#define TYPE_POINTER 11 #define TYPE_UNKNOWN 20 #define FLAG_LEFT 0x1 @@ -89,31 +89,9 @@ generic_write(SprintfState* ss, const char* src, size_t srclen) return (*ss->stuff)(ss, src, srclen); } -inline bool -generic_write(SprintfState* ss, const char16_t* src, size_t srclen) -{ - const size_t CHUNK_SIZE = 64; - char chunk[CHUNK_SIZE]; - - size_t j = 0; - size_t i = 0; - while (i < srclen) { - // FIXME: truncates characters to 8 bits - chunk[j++] = char(src[i++]); - - if (j == CHUNK_SIZE || i == srclen) { - if (!(*ss->stuff)(ss, chunk, j)) - return false; - j = 0; - } - } - return true; -} - // Fill into the buffer using the data in src -template static bool -fill2(SprintfState* ss, const Char* src, int srclen, int width, int flags) +fill2(SprintfState* ss, const char* src, int srclen, int width, int flags) { char space = ' '; @@ -318,19 +296,16 @@ static bool cvt_f(SprintfState* ss, double d, const char* fmt0, const char* fmt1 } static inline const char* generic_null_str(const char*) { return "(null)"; } -static inline const char16_t* generic_null_str(const char16_t*) { return u"(null)"; } static inline size_t generic_strlen(const char* s) { return strlen(s); } -static inline size_t generic_strlen(const char16_t* s) { return js_strlen(s); } /* * Convert a string into its printable form. "width" is the output * width. "prec" is the maximum number of characters of "s" to output, * where -1 means until NUL. */ -template static bool -cvt_s(SprintfState* ss, const Char* s, int width, int prec, int flags) +cvt_s(SprintfState* ss, const char* s, int width, int prec, int flags) { if (prec == 0) return true; @@ -452,23 +427,24 @@ BuildArgArray(const char* fmt, va_list ap, NumArgStateVector& nas) // size nas[cn].type = TYPE_INTN; if (c == 'h') { - nas[cn].type = TYPE_INT16; + nas[cn].type = TYPE_SHORT; c = *p++; } else if (c == 'L') { - // XXX not quite sure here - nas[cn].type = TYPE_INT64; + nas[cn].type = TYPE_LONGLONG; c = *p++; } else if (c == 'l') { - nas[cn].type = TYPE_INT32; + nas[cn].type = TYPE_LONG; c = *p++; if (c == 'l') { - nas[cn].type = TYPE_INT64; + nas[cn].type = TYPE_LONGLONG; c = *p++; } } else if (c == 'z' || c == 'I') { - static_assert(sizeof(size_t) == sizeof(int32_t) || sizeof(size_t) == sizeof(int64_t), + static_assert(sizeof(size_t) == sizeof(int) || sizeof(size_t) == sizeof(long) || + sizeof(size_t) == sizeof(long long), "size_t is not one of the expected sizes"); - nas[cn].type = sizeof(size_t) == sizeof(int64_t) ? TYPE_INT64 : TYPE_INT32; + nas[cn].type = sizeof(size_t) == sizeof(int) ? TYPE_INTN : + sizeof(size_t) == sizeof(long) ? TYPE_LONG : TYPE_LONGLONG; c = *p++; } @@ -490,16 +466,7 @@ BuildArgArray(const char* fmt, va_list ap, NumArgStateVector& nas) break; case 'p': - // XXX should use cpp - if (sizeof(void*) == sizeof(int32_t)) { - nas[cn].type = TYPE_UINT32; - } else if (sizeof(void*) == sizeof(int64_t)) { - nas[cn].type = TYPE_UINT64; - } else if (sizeof(void*) == sizeof(int)) { - nas[cn].type = TYPE_UINTN; - } else { - nas[cn].type = TYPE_UNKNOWN; - } + nas[cn].type = TYPE_POINTER; break; case 'C': @@ -512,7 +479,7 @@ BuildArgArray(const char* fmt, va_list ap, NumArgStateVector& nas) break; case 's': - nas[cn].type = (nas[cn].type == TYPE_UINT16) ? TYPE_WSTRING : TYPE_STRING; + nas[cn].type = TYPE_STRING; break; case 'n': @@ -544,18 +511,18 @@ BuildArgArray(const char* fmt, va_list ap, NumArgStateVector& nas) VARARGS_ASSIGN(nas[cn].ap, ap); switch (nas[cn].type) { - case TYPE_INT16: - case TYPE_UINT16: + case TYPE_SHORT: + case TYPE_USHORT: case TYPE_INTN: case TYPE_UINTN: (void) va_arg(ap, int); break; - case TYPE_INT32: (void) va_arg(ap, int32_t); break; - case TYPE_UINT32: (void) va_arg(ap, uint32_t); break; - case TYPE_INT64: (void) va_arg(ap, int64_t); break; - case TYPE_UINT64: (void) va_arg(ap, uint64_t); break; + case TYPE_LONG: (void) va_arg(ap, long); break; + case TYPE_ULONG: (void) va_arg(ap, unsigned long); break; + case TYPE_LONGLONG: (void) va_arg(ap, long long); break; + case TYPE_ULONGLONG: (void) va_arg(ap, unsigned long long); break; case TYPE_STRING: (void) va_arg(ap, char*); break; - case TYPE_WSTRING: (void) va_arg(ap, char16_t*); break; case TYPE_INTSTR: (void) va_arg(ap, int*); break; case TYPE_DOUBLE: (void) va_arg(ap, double); break; + case TYPE_POINTER: (void) va_arg(ap, void*); break; default: MOZ_CRASH(); } @@ -576,14 +543,13 @@ dosprintf(SprintfState* ss, const char* fmt, va_list ap) int flags, width, prec, radix, type; union { char ch; - char16_t wch; int i; long l; - int64_t ll; + long long ll; double d; const char* s; - const char16_t* ws; int* ip; + void* p; } u; const char* fmt0; static const char hex[] = "0123456789abcdef"; @@ -685,23 +651,24 @@ dosprintf(SprintfState* ss, const char* fmt, va_list ap) // size type = TYPE_INTN; if (c == 'h') { - type = TYPE_INT16; + type = TYPE_SHORT; c = *fmt++; } else if (c == 'L') { - // XXX not quite sure here - type = TYPE_INT64; + type = TYPE_LONGLONG; c = *fmt++; } else if (c == 'l') { - type = TYPE_INT32; + type = TYPE_LONG; c = *fmt++; if (c == 'l') { - type = TYPE_INT64; + type = TYPE_LONGLONG; c = *fmt++; } } else if (c == 'z' || c == 'I') { - static_assert(sizeof(size_t) == sizeof(int32_t) || sizeof(size_t) == sizeof(int64_t), + static_assert(sizeof(size_t) == sizeof(int) || sizeof(size_t) == sizeof(long) || + sizeof(size_t) == sizeof(long long), "size_t is not one of the expected sizes"); - type = sizeof(size_t) == sizeof(int64_t) ? TYPE_INT64 : TYPE_INT32; + type = sizeof(size_t) == sizeof(int) ? TYPE_INTN : + sizeof(size_t) == sizeof(long) ? TYPE_LONG : TYPE_LONGLONG; c = *fmt++; } @@ -735,15 +702,15 @@ dosprintf(SprintfState* ss, const char* fmt, va_list ap) fetch_and_convert: switch (type) { - case TYPE_INT16: + case TYPE_SHORT: u.l = va_arg(ap, int); if (u.l < 0) { u.l = -u.l; flags |= FLAG_NEG; } goto do_long; - case TYPE_UINT16: - u.l = va_arg(ap, int) & 0xffff; + case TYPE_USHORT: + u.l = (unsigned short) va_arg(ap, unsigned int); goto do_long; case TYPE_INTN: u.l = va_arg(ap, int); @@ -756,30 +723,33 @@ dosprintf(SprintfState* ss, const char* fmt, va_list ap) u.l = (long)va_arg(ap, unsigned int); goto do_long; - case TYPE_INT32: - u.l = va_arg(ap, int32_t); + case TYPE_LONG: + u.l = va_arg(ap, long); if (u.l < 0) { u.l = -u.l; flags |= FLAG_NEG; } goto do_long; - case TYPE_UINT32: - u.l = (long)va_arg(ap, uint32_t); + case TYPE_ULONG: + u.l = (long)va_arg(ap, unsigned long); do_long: if (!cvt_l(ss, u.l, width, prec, radix, type, flags, hexp)) return false; break; - case TYPE_INT64: - u.ll = va_arg(ap, int64_t); + case TYPE_LONGLONG: + u.ll = va_arg(ap, long long); if (u.ll < 0) { u.ll = -u.ll; flags |= FLAG_NEG; } goto do_longlong; - case TYPE_UINT64: - u.ll = va_arg(ap, uint64_t); + case TYPE_POINTER: + u.ll = (uintptr_t)va_arg(ap, void*); + goto do_longlong; + case TYPE_ULONGLONG: + u.ll = va_arg(ap, unsigned long long); do_longlong: if (!cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp)) return false; @@ -816,7 +786,7 @@ dosprintf(SprintfState* ss, const char* fmt, va_list ap) } } switch (type) { - case TYPE_INT16: + case TYPE_SHORT: case TYPE_INTN: u.ch = va_arg(ap, int); if (!(*ss->stuff)(ss, &u.ch, 1)) @@ -832,16 +802,7 @@ dosprintf(SprintfState* ss, const char* fmt, va_list ap) break; case 'p': - if (sizeof(void*) == sizeof(int32_t)) { - type = TYPE_UINT32; - } else if (sizeof(void*) == sizeof(int64_t)) { - type = TYPE_UINT64; - } else if (sizeof(void*) == sizeof(int)) { - type = TYPE_UINTN; - } else { - MOZ_ASSERT(0); - break; - } + type = TYPE_POINTER; radix = 16; goto fetch_and_convert; @@ -856,15 +817,9 @@ dosprintf(SprintfState* ss, const char* fmt, va_list ap) #endif case 's': - if(type == TYPE_INT16) { - u.ws = va_arg(ap, const char16_t*); - if (!cvt_s(ss, u.ws, width, prec, flags)) - return false; - } else { - u.s = va_arg(ap, const char*); - if (!cvt_s(ss, u.s, width, prec, flags)) - return false; - } + u.s = va_arg(ap, const char*); + if (!cvt_s(ss, u.s, width, prec, flags)) + return false; break; case 'n': @@ -1004,18 +959,18 @@ JS_vsprintf_append(char* last, const char* fmt, va_list ap) return ss.base; } -#undef TYPE_INT16 -#undef TYPE_UINT16 +#undef TYPE_SHORT +#undef TYPE_USHORT #undef TYPE_INTN #undef TYPE_UINTN -#undef TYPE_INT32 -#undef TYPE_UINT32 -#undef TYPE_INT64 -#undef TYPE_UINT64 +#undef TYPE_LONG +#undef TYPE_ULONG +#undef TYPE_LONGLONG +#undef TYPE_ULONGLONG #undef TYPE_STRING #undef TYPE_DOUBLE #undef TYPE_INTSTR -#undef TYPE_WSTRING +#undef TYPE_POINTER #undef TYPE_UNKNOWN #undef FLAG_LEFT diff --git a/js/src/jsprf.h b/js/src/jsprf.h index 3bdbe638472c..b84b5a5c9864 100644 --- a/js/src/jsprf.h +++ b/js/src/jsprf.h @@ -14,11 +14,13 @@ ** %x - unsigned hex ** %X - unsigned uppercase hex ** %o - unsigned octal -** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above -** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above -** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above -** %s - ascii string -** %hs - ucs2 string +** %hd, %hu, %hx, %hX, %ho - "short" versions of above +** %ld, %lu, %lx, %lX, %lo - "long" versions of above +** %lld, %llu, %llx, %llX, %llo - "long long" versions of above +** %zd, %zo, %zu, %zx, %zX - size_t versions of above +** %Id, %Io, %Iu, %Ix, %IX - size_t versions of above (for Windows compat) +** You should use PRI*SIZE macros instead +** %s - string ** %c - character ** %p - pointer (deals with machine dependent pointer size) ** %f - float @@ -37,7 +39,8 @@ ** buffer on success, nullptr on failure. Call "JS_smprintf_free" to release ** the memory returned. */ -extern JS_PUBLIC_API(char*) JS_smprintf(const char* fmt, ...); +extern JS_PUBLIC_API(char*) JS_smprintf(const char* fmt, ...) + MOZ_FORMAT_PRINTF(1, 2); /* ** Free the memory allocated, for the caller, by JS_smprintf @@ -51,7 +54,8 @@ extern JS_PUBLIC_API(void) JS_smprintf_free(char* mem); ** will allocate the initial string. The return value is the new value of ** last for subsequent calls, or nullptr if there is a malloc failure. */ -extern JS_PUBLIC_API(char*) JS_sprintf_append(char* last, const char* fmt, ...); +extern JS_PUBLIC_API(char*) JS_sprintf_append(char* last, const char* fmt, ...) + MOZ_FORMAT_PRINTF(2, 3); /* ** va_list forms of the above. diff --git a/js/src/moz.build b/js/src/moz.build index bf2081f7a7b5..546a396753a7 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -784,7 +784,7 @@ if CONFIG['JS_HAS_CTYPES']: DEFINES['FFI_BUILDING'] = True if CONFIG['GNU_CXX']: - CXXFLAGS += ['-Wno-shadow'] + CXXFLAGS += ['-Wno-shadow', '-Werror=format'] # Suppress warnings in third-party code. if CONFIG['CLANG_CXX']: diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 4ffda095c894..67da80bcf8dd 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -5247,7 +5247,7 @@ ReflectTrackedOptimizations(JSContext* cx, unsigned argc, Value* vp) uint8_t* addr = ion->method()->raw() + endOffset; entry.youngestFrameLocationAtAddr(rt, addr, &script, &pc); - if (!sp.jsprintf("{\"location\":\"%s:%u\",\"offset\":%u,\"index\":%u}%s", + if (!sp.jsprintf("{\"location\":\"%s:%" PRIuSIZE "\",\"offset\":%" PRIuSIZE ",\"index\":%u}%s", script->filename(), script->lineno(), script->pcToOffset(pc), index, iter.more() ? "," : "")) { diff --git a/js/src/shell/jsoptparse.cpp b/js/src/shell/jsoptparse.cpp index 5e1a3aa09fdc..eaf4042d3bf4 100644 --- a/js/src/shell/jsoptparse.cpp +++ b/js/src/shell/jsoptparse.cpp @@ -264,7 +264,7 @@ OptionParser::extractValue(size_t argc, char** argv, size_t* i, char** value) if (eq) { *value = eq + 1; if (*value[0] == '\0') - return error("A value is required for option %.*s", eq - argv[*i], argv[*i]); + return error("A value is required for option %.*s", (int) (eq - argv[*i]), argv[*i]); return Okay; } diff --git a/js/src/shell/jsoptparse.h b/js/src/shell/jsoptparse.h index b2a24348186a..274978130ea3 100644 --- a/js/src/shell/jsoptparse.h +++ b/js/src/shell/jsoptparse.h @@ -228,7 +228,7 @@ class OptionParser Option* findArgument(const char* name); const Option* findArgument(const char* name) const; - Result error(const char* fmt, ...); + Result error(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3); Result extractValue(size_t argc, char** argv, size_t* i, char** value); Result handleArg(size_t argc, char** argv, size_t* i, bool* optsAllowed); Result handleOption(Option* opt, size_t argc, char** argv, size_t* i, bool* optsAllowed); diff --git a/js/src/shell/moz.build b/js/src/shell/moz.build index 77475b241fa8..72ea8145cc31 100644 --- a/js/src/shell/moz.build +++ b/js/src/shell/moz.build @@ -51,7 +51,7 @@ shellmoduleloader.inputs = [ ] if CONFIG['GNU_CXX']: - CXXFLAGS += ['-Wno-shadow'] + CXXFLAGS += ['-Wno-shadow', '-Werror=format'] # This is intended as a temporary workaround to enable VS2015. if CONFIG['_MSC_VER']: diff --git a/js/src/vm/CodeCoverage.cpp b/js/src/vm/CodeCoverage.cpp index 280256b66eef..e7146a32a3be 100644 --- a/js/src/vm/CodeCoverage.cpp +++ b/js/src/vm/CodeCoverage.cpp @@ -91,16 +91,16 @@ LCovSource::exportInto(GenericPrinter& out) const outFN_.exportInto(out); outFNDA_.exportInto(out); - out.printf("FNF:%d\n", numFunctionsFound_); - out.printf("FNH:%d\n", numFunctionsHit_); + out.printf("FNF:%" PRIuSIZE "\n", numFunctionsFound_); + out.printf("FNH:%" PRIuSIZE "\n", numFunctionsHit_); outBRDA_.exportInto(out); - out.printf("BRF:%d\n", numBranchesFound_); - out.printf("BRH:%d\n", numBranchesHit_); + out.printf("BRF:%" PRIuSIZE "\n", numBranchesFound_); + out.printf("BRH:%" PRIuSIZE "\n", numBranchesHit_); outDA_.exportInto(out); - out.printf("LF:%d\n", numLinesInstrumented_); - out.printf("LH:%d\n", numLinesHit_); + out.printf("LF:%" PRIuSIZE "\n", numLinesInstrumented_); + out.printf("LH:%" PRIuSIZE "\n", numLinesHit_); out.put("end_of_record\n"); } @@ -130,7 +130,7 @@ bool LCovSource::writeScript(JSScript* script) { numFunctionsFound_++; - outFN_.printf("FN:%d,", script->lineno()); + outFN_.printf("FN:%" PRIuSIZE ",", script->lineno()); if (!writeScriptName(outFN_, script)) return false; outFN_.put("\n", 1); @@ -191,7 +191,7 @@ LCovSource::writeScript(JSScript* script) } if (oldLine != lineno && fallsthrough) { - outDA_.printf("DA:%d,%" PRIu64 "\n", lineno, hits); + outDA_.printf("DA:%" PRIuSIZE ",%" PRIu64 "\n", lineno, hits); // Count the number of lines instrumented & hit. numLinesInstrumented_++; @@ -220,13 +220,13 @@ LCovSource::writeScript(JSScript* script) } uint64_t taken = hits - fallthroughHits; - outBRDA_.printf("BRDA:%d,%d,0,", lineno, branchId); + outBRDA_.printf("BRDA:%" PRIuSIZE ",%" PRIuSIZE ",0,", lineno, branchId); if (taken) outBRDA_.printf("%" PRIu64 "\n", taken); else outBRDA_.put("-\n", 2); - outBRDA_.printf("BRDA:%d,%d,1,", lineno, branchId); + outBRDA_.printf("BRDA:%" PRIuSIZE ",%" PRIuSIZE ",1,", lineno, branchId); if (fallthroughHits) outBRDA_.printf("%" PRIu64 "\n", fallthroughHits); else @@ -308,7 +308,8 @@ LCovSource::writeScript(JSScript* script) caseHits -= fallsThroughHits; } - outBRDA_.printf("BRDA:%d,%d,%d,", lineno, branchId, caseId); + outBRDA_.printf("BRDA:%" PRIuSIZE ",%" PRIuSIZE ",%" PRIuSIZE ",", + lineno, branchId, caseId); if (caseHits) outBRDA_.printf("%" PRIu64 "\n", caseHits); else @@ -359,7 +360,8 @@ LCovSource::writeScript(JSScript* script) } if (defaultHasOwnClause) { - outBRDA_.printf("BRDA:%d,%d,%d,", lineno, branchId, caseId); + outBRDA_.printf("BRDA:%" PRIuSIZE ",%" PRIuSIZE ",%" PRIuSIZE ",", + lineno, branchId, caseId); if (defaultHits) outBRDA_.printf("%" PRIu64 "\n", defaultHits); else diff --git a/js/src/vm/Printer.h b/js/src/vm/Printer.h index ae70d59fa114..3ee76da44d5e 100644 --- a/js/src/vm/Printer.h +++ b/js/src/vm/Printer.h @@ -43,7 +43,7 @@ class GenericPrinter } // Prints a formatted string into the buffer. - virtual int printf(const char* fmt, ...); + virtual int printf(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3); virtual int vprintf(const char* fmt, va_list ap); // Report that a string operation failed to get the memory it requested. The @@ -115,7 +115,7 @@ class Sprinter final : public GenericPrinter // Format the given format/arguments as if by JS_vsmprintf, then put it. // Return true on success, else return false and report an error (typically // OOM). - MOZ_MUST_USE bool jsprintf(const char* fmt, ...); + MOZ_MUST_USE bool jsprintf(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3); // Prints a formatted string into the buffer. virtual int vprintf(const char* fmt, va_list ap) override; @@ -157,7 +157,7 @@ class Fprinter final : public GenericPrinter using GenericPrinter::put; // pick up |inline int put(const char* s);| // Prints a formatted string into the buffer. - virtual int printf(const char* fmt, ...) override; + virtual int printf(const char* fmt, ...) override MOZ_FORMAT_PRINTF(2, 3); virtual int vprintf(const char* fmt, va_list ap) override; }; @@ -203,7 +203,7 @@ class LSprinter final : public GenericPrinter using GenericPrinter::put; // pick up |inline int put(const char* s);| // Prints a formatted string into the buffer. - virtual int printf(const char* fmt, ...) override; + virtual int printf(const char* fmt, ...) override MOZ_FORMAT_PRINTF(2, 3); virtual int vprintf(const char* fmt, va_list ap) override; // Report that a string operation failed to get the memory it requested. The diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index 1d38c48239da..eed04d3fab4f 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -10,6 +10,7 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/PodOperations.h" #include "mozilla/RangedPtr.h" +#include "mozilla/SizePrintfMacros.h" #include "mozilla/TypeTraits.h" #include "mozilla/Unused.h" @@ -187,7 +188,7 @@ JSString::dumpRepresentationHeader(FILE* fp, int indent, const char* subclass) c uint32_t flags = d.u1.flags; // Print the string's address as an actual C++ expression, to facilitate // copy-and-paste into a debugger. - fprintf(fp, "((%s*) %p) length: %zu flags: 0x%x", subclass, this, length(), flags); + fprintf(fp, "((%s*) %p) length: %" PRIuSIZE " flags: 0x%x", subclass, this, length(), flags); if (flags & FLAT_BIT) fputs(" FLAT", fp); if (flags & HAS_BASE_BIT) fputs(" HAS_BASE", fp); if (flags & INLINE_CHARS_BIT) fputs(" INLINE_CHARS", fp); @@ -703,7 +704,7 @@ JSDependentString::dumpRepresentation(FILE* fp, int indent) const dumpRepresentationHeader(fp, indent, "JSDependentString"); indent += 2; - fprintf(fp, "%*soffset: %zu\n", indent, "", baseOffset()); + fprintf(fp, "%*soffset: %" PRIuSIZE "\n", indent, "", baseOffset()); fprintf(fp, "%*sbase: ", indent, ""); base()->dumpRepresentation(fp, indent); } @@ -1363,7 +1364,7 @@ JSExtensibleString::dumpRepresentation(FILE* fp, int indent) const dumpRepresentationHeader(fp, indent, "JSExtensibleString"); indent += 2; - fprintf(fp, "%*scapacity: %zu\n", indent, "", capacity()); + fprintf(fp, "%*scapacity: %" PRIuSIZE "\n", indent, "", capacity()); dumpRepresentationChars(fp, indent); } diff --git a/js/src/vm/TraceLoggingGraph.cpp b/js/src/vm/TraceLoggingGraph.cpp index 16d270b7e54a..6f6792e98040 100644 --- a/js/src/vm/TraceLoggingGraph.cpp +++ b/js/src/vm/TraceLoggingGraph.cpp @@ -50,6 +50,7 @@ TraceLoggerGraphState* traceLoggerGraphState = nullptr; // are allowed, with %u standing for a full 32-bit number and %d standing for // an up to 3-digit number. static js::UniqueChars +MOZ_FORMAT_PRINTF(1, 2) AllocTraceLogFilename(const char* pattern, ...) { js::UniqueChars filename; diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp index 97a92fccee95..762edf71d3a5 100644 --- a/js/src/vm/TypeInference.cpp +++ b/js/src/vm/TypeInference.cpp @@ -237,6 +237,7 @@ js::InferSpewImpl(const char* fmt, ...) #endif MOZ_NORETURN MOZ_COLD static void +MOZ_FORMAT_PRINTF(2, 3) TypeFailure(JSContext* cx, const char* fmt, ...) { char msgbuf[1024]; /* Larger error messages will be truncated */ @@ -3288,7 +3289,7 @@ js::TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc, TypeSet:: if (types->hasType(type)) return; - InferSpew(ISpewOps, "bytecodeType: %p %05u: %s", + InferSpew(ISpewOps, "bytecodeType: %p %05" PRIuSIZE ": %s", script, script->pcToOffset(pc), TypeSet::TypeString(type)); types->addType(cx, type); } diff --git a/js/src/vm/TypeInference.h b/js/src/vm/TypeInference.h index ee243bf299f0..26522727c98f 100644 --- a/js/src/vm/TypeInference.h +++ b/js/src/vm/TypeInference.h @@ -1296,7 +1296,7 @@ const char * InferSpewColor(TypeConstraint* constraint); const char * InferSpewColor(TypeSet* types); #define InferSpew(channel, ...) if (InferSpewActive(channel)) { InferSpewImpl(__VA_ARGS__); } else {} -void InferSpewImpl(const char* fmt, ...); +void InferSpewImpl(const char* fmt, ...) MOZ_FORMAT_PRINTF(1, 2); /* Check that the type property for id in group contains value. */ bool ObjectGroupHasProperty(JSContext* cx, ObjectGroup* group, jsid id, const Value& value); diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index 2f0c0ff40a56..95c214867758 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -154,6 +154,7 @@ private: }; static nsresult +MOZ_FORMAT_PRINTF(2, 3) ReportOnCallerUTF8(JSContext* callerContext, const char* format, ...) { if (!callerContext) { @@ -177,6 +178,7 @@ ReportOnCallerUTF8(JSContext* callerContext, } static nsresult +MOZ_FORMAT_PRINTF(2, 3) ReportOnCallerUTF8(JSCLContextHelper& helper, const char* format, ...) { diff --git a/js/xpconnect/src/XPCThrower.cpp b/js/xpconnect/src/XPCThrower.cpp index ad479b4e3eb8..4a37e1554287 100644 --- a/js/xpconnect/src/XPCThrower.cpp +++ b/js/xpconnect/src/XPCThrower.cpp @@ -116,9 +116,9 @@ XPCThrower::ThrowBadResult(nsresult rv, nsresult result, XPCCallContext& ccx) format = ""; if (nsXPCException::NameAndFormatForNSResult(result, &name, nullptr) && name) - sz = JS_smprintf("%s 0x%x (%s)", format, result, name); + sz = JS_smprintf("%s 0x%x (%s)", format, (unsigned) result, name); else - sz = JS_smprintf("%s 0x%x", format, result); + sz = JS_smprintf("%s 0x%x", format, (unsigned) result); NS_ENSURE_TRUE_VOID(sz); if (sz && sVerbose) diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index 518c8c94ce62..0cf82633c6c9 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -971,7 +971,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex, const char* str = "IDL methods marked with [implicit_jscontext] " "or [optional_argc] may not be implemented in JS"; // Throw and warn for good measure. - JS_ReportErrorASCII(cx, str); + JS_ReportErrorASCII(cx, "%s", str); NS_WARNING(str); return CheckForException(ccx, aes, name, GetInterfaceName()); } diff --git a/js/xpconnect/src/moz.build b/js/xpconnect/src/moz.build index 9108fd66aca2..94d58577cc79 100644 --- a/js/xpconnect/src/moz.build +++ b/js/xpconnect/src/moz.build @@ -72,4 +72,4 @@ if CONFIG['MOZ_B2G_BT']: ] if CONFIG['GNU_CXX']: - CXXFLAGS += ['-Wno-shadow'] + CXXFLAGS += ['-Wno-shadow', '-Werror=format'] diff --git a/js/xpconnect/wrappers/AccessCheck.cpp b/js/xpconnect/wrappers/AccessCheck.cpp index 66e96d04c34a..9f468931f197 100644 --- a/js/xpconnect/wrappers/AccessCheck.cpp +++ b/js/xpconnect/wrappers/AccessCheck.cpp @@ -274,7 +274,7 @@ static void EnterAndThrowASCII(JSContext* cx, JSObject* wrapper, const char* msg) { JSAutoCompartment ac(cx, wrapper); - JS_ReportErrorASCII(cx, msg); + JS_ReportErrorASCII(cx, "%s", msg); } bool diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 487c5a2bf167..8c7e66c9aa1d 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -12805,11 +12805,7 @@ Iterator::AppendItemsToList(const Iterator& aEnd, } // Move our entire list of items into the empty target list. - // XXX: If LinkedList supports move assignment, we could use - // aTargetList.mItems = Move(mList.mItems); - aTargetList.mItems.~LinkedList(); - new (&aTargetList.mItems) LinkedList( - Move(mList.mItems)); + aTargetList.mItems = Move(mList.mItems); // Copy over the various counters aTargetList.mInlineCount = mList.mInlineCount; diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index a5431e2ce3a7..1178d2180315 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1410,12 +1410,11 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, // calculating hypothetical position of absolutely-positioned // frames. The line cursor is immediately cleared afterward to // avoid affecting the display list generation. - SetupLineCursor(); + AutoLineCursorSetup autoLineCursor(this); absoluteContainer->Reflow(this, aPresContext, *reflowInput, state.mReflowStatus, containingBlock, flags, &aMetrics.mOverflowAreas); - ClearLineCursor(); } } diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index ec009fcf134f..8db16e8bb568 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -153,8 +153,12 @@ public: virtual mozilla::a11y::AccType AccessibleType() override; #endif - // line cursor methods to speed up searching for the line(s) - // containing a point. The basic idea is that we set the cursor + // Line cursor methods to speed up line searching in which one query + // result is expected to be close to the next in general. This is + // mainly for searching line(s) containing a point. It is also used + // as a cache for local computation. Use AutoLineCursorSetup for the + // latter case so that it wouldn't interact unexpectedly with the + // former. The basic idea for the former is that we set the cursor // property if the lines' overflowArea.VisualOverflow().ys and // overflowArea.VisualOverflow().yMosts are non-decreasing // (considering only non-empty overflowArea.VisualOverflow()s; empty @@ -179,6 +183,36 @@ public: // building the display list of this frame. void SetupLineCursor(); + /** + * Helper RAII class for automatically set and clear line cursor for + * temporary use. If the frame already has line cursor, this would be + * a no-op. + */ + class MOZ_STACK_CLASS AutoLineCursorSetup + { + public: + explicit AutoLineCursorSetup(nsBlockFrame* aFrame) + : mFrame(aFrame) + , mOrigCursor(aFrame->GetLineCursor()) + { + if (!mOrigCursor) { + mFrame->SetupLineCursor(); + } + } + ~AutoLineCursorSetup() + { + if (mOrigCursor) { + mFrame->Properties().Set(LineCursorProperty(), mOrigCursor); + } else { + mFrame->ClearLineCursor(); + } + } + + private: + nsBlockFrame* mFrame; + nsLineBox* mOrigCursor; + }; + virtual void ChildIsDirty(nsIFrame* aChild) override; virtual bool IsVisibleInSelection(nsISelection* aSelection) override; @@ -368,9 +402,9 @@ protected: #endif NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(LineCursorProperty, nsLineBox) + bool HasLineCursor() { return GetStateBits() & NS_BLOCK_HAS_LINE_CURSOR; } nsLineBox* GetLineCursor() { - return (GetStateBits() & NS_BLOCK_HAS_LINE_CURSOR) ? - Properties().Get(LineCursorProperty()) : nullptr; + return HasLineCursor() ? Properties().Get(LineCursorProperty()) : nullptr; } nsLineBox* NewLineBox(nsIFrame* aFrame, bool aIsBlock) { diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 8d0b11b65dcd..8bba88c0304e 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -9634,17 +9634,10 @@ static void TransformChars(nsTextFrame* aFrame, const nsStyleText* aStyle, } static bool -LineEndsInHardLineBreak(nsTextFrame* aFrame) +LineEndsInHardLineBreak(nsTextFrame* aFrame, nsBlockFrame* aLineContainer) { - nsIFrame* lineContainer = FindLineContainer(aFrame); - nsBlockFrame* block = do_QueryFrame(lineContainer); - if (!block) { - // Weird situation where we have a line layout without a block. - // No soft breaks occur in this situation. - return true; - } bool foundValidLine; - nsBlockInFlowLineIterator iter(block, aFrame, &foundValidLine); + nsBlockInFlowLineIterator iter(aLineContainer, aFrame, &foundValidLine); if (!foundValidLine) { NS_ERROR("Invalid line!"); return true; @@ -9662,11 +9655,13 @@ nsTextFrame::GetRenderedText(uint32_t aStartOffset, // The handling of offsets could be more efficient... RenderedText result; + nsBlockFrame* lineContainer = nullptr; nsTextFrame* textFrame; const nsTextFragment* textFrag = mContent->GetText(); uint32_t offsetInRenderedString = 0; bool haveOffsets = false; + Maybe autoLineCursor; for (textFrame = this; textFrame; textFrame = static_cast(textFrame->GetNextContinuation())) { if (textFrame->GetStateBits() & NS_FRAME_IS_DIRTY) { @@ -9682,10 +9677,30 @@ nsTextFrame::GetRenderedText(uint32_t aStartOffset, } gfxSkipCharsIterator tmpIter = iter; + // Whether we need to trim whitespaces after the text frame. + bool trimAfter; + if (!textFrame->IsAtEndOfLine() || + aTrimTrailingWhitespace != + TrailingWhitespace::TRIM_TRAILING_WHITESPACE) { + trimAfter = false; + } else if (nsBlockFrame* thisLc = + do_QueryFrame(FindLineContainer(textFrame))) { + if (thisLc != lineContainer) { + // Setup line cursor when needed. + lineContainer = thisLc; + autoLineCursor.reset(); + autoLineCursor.emplace(lineContainer); + } + trimAfter = LineEndsInHardLineBreak(textFrame, lineContainer); + } else { + // Weird situation where we have a line layout without a block. + // No soft breaks occur in this situation. + trimAfter = true; + } + // Skip to the start of the text run, past ignored chars at start of line - TrimmedOffsets trimmedOffsets = textFrame->GetTrimmedOffsets(textFrag, - textFrame->IsAtEndOfLine() && LineEndsInHardLineBreak(textFrame) && - aTrimTrailingWhitespace == TrailingWhitespace::TRIM_TRAILING_WHITESPACE); + TrimmedOffsets trimmedOffsets = + textFrame->GetTrimmedOffsets(textFrag, trimAfter); bool trimmedSignificantNewline = trimmedOffsets.GetEnd() < GetContentEnd() && HasSignificantTerminalNewline(); diff --git a/mfbt/Attributes.h b/mfbt/Attributes.h index f7f8a0c39291..df6172f31b5a 100644 --- a/mfbt/Attributes.h +++ b/mfbt/Attributes.h @@ -569,4 +569,36 @@ #endif /* __cplusplus */ +/** + * Printf style formats. MOZ_FORMAT_PRINTF can be used to annotate a + * function or method that is "printf-like"; this will let (some) + * compilers check that the arguments match the template string. + * + * This macro takes two arguments. The first argument is the argument + * number of the template string. The second argument is the argument + * number of the '...' argument holding the arguments. + * + * Argument numbers start at 1. Note that the implicit "this" + * argument of a non-static member function counts as an argument. + * + * So, for a simple case like: + * void print_something (int whatever, const char *fmt, ...); + * The corresponding annotation would be + * MOZ_FORMAT_PRINTF(2, 3) + * However, if "print_something" were a non-static member function, + * then the annotation would be: + * MOZ_FORMAT_PRINTF(3, 4) + * + * Note that the checking is limited to standards-conforming + * printf-likes, and in particular this should not be used for + * PR_snprintf and friends, which are "printf-like" but which assign + * different meanings to the various formats. + */ +#ifdef __GNUC__ +#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) \ + __attribute__ ((format (printf, stringIndex, firstToCheck))) +#else +#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) +#endif + #endif /* mozilla_Attributes_h */ diff --git a/mfbt/LinkedList.h b/mfbt/LinkedList.h index e0f2a03793ae..70641699fb8f 100644 --- a/mfbt/LinkedList.h +++ b/mfbt/LinkedList.h @@ -125,34 +125,23 @@ public: mIsSentinel(false) { } - LinkedListElement(LinkedListElement&& other) - : mIsSentinel(other.mIsSentinel) + /* + * Moves |aOther| into |*this|. If |aOther| is already in a list, then + * |aOther| is removed from the list and replaced by |*this|. + */ + LinkedListElement(LinkedListElement&& aOther) + : mIsSentinel(aOther.mIsSentinel) { - if (!other.isInList()) { - mNext = this; - mPrev = this; - return; - } + adjustLinkForMove(Move(aOther)); + } - MOZ_ASSERT(other.mNext->mPrev == &other); - MOZ_ASSERT(other.mPrev->mNext == &other); - - /* - * Initialize |this| with |other|'s mPrev/mNext pointers, and adjust those - * element to point to this one. - */ - mNext = other.mNext; - mPrev = other.mPrev; - - mNext->mPrev = this; - mPrev->mNext = this; - - /* - * Adjust |other| so it doesn't think it's in a list. This makes it - * safely destructable. - */ - other.mNext = &other; - other.mPrev = &other; + LinkedListElement& operator=(LinkedListElement&& aOther) + { + MOZ_ASSERT(mIsSentinel == aOther.mIsSentinel, "Mismatch NodeKind!"); + MOZ_ASSERT(!isInList(), + "Assigning to an element in a list messes up that list!"); + adjustLinkForMove(Move(aOther)); + return *this; } ~LinkedListElement() @@ -233,15 +222,15 @@ public: private: friend class LinkedList; - enum NodeKind { - NODE_KIND_NORMAL, - NODE_KIND_SENTINEL + enum class NodeKind { + Normal, + Sentinel }; explicit LinkedListElement(NodeKind nodeKind) : mNext(this), mPrev(this), - mIsSentinel(nodeKind == NODE_KIND_SENTINEL) + mIsSentinel(nodeKind == NodeKind::Sentinel) { } /* @@ -287,7 +276,39 @@ private: this->mPrev = listElem; } -private: + /* + * Adjust mNext and mPrev for implementing move constructor and move + * assignment. + */ + void adjustLinkForMove(LinkedListElement&& aOther) + { + if (!aOther.isInList()) { + mNext = this; + mPrev = this; + return; + } + + MOZ_ASSERT(aOther.mNext->mPrev == &aOther); + MOZ_ASSERT(aOther.mPrev->mNext == &aOther); + + /* + * Initialize |this| with |aOther|'s mPrev/mNext pointers, and adjust those + * element to point to this one. + */ + mNext = aOther.mNext; + mPrev = aOther.mPrev; + + mNext->mPrev = this; + mPrev->mNext = this; + + /* + * Adjust |aOther| so it doesn't think it's in a list. This makes it + * safely destructable. + */ + aOther.mNext = &aOther; + aOther.mPrev = &aOther; + } + LinkedListElement& operator=(const LinkedListElement& aOther) = delete; LinkedListElement(const LinkedListElement& aOther) = delete; }; @@ -319,12 +340,19 @@ public: } }; - LinkedList() : sentinel(LinkedListElement::NODE_KIND_SENTINEL) { } + LinkedList() : sentinel(LinkedListElement::NodeKind::Sentinel) { } LinkedList(LinkedList&& aOther) : sentinel(mozilla::Move(aOther.sentinel)) { } + LinkedList& operator=(LinkedList&& aOther) + { + MOZ_ASSERT(isEmpty(), "Assigning to a non-empty list leaks elements in that list!"); + sentinel = mozilla::Move(aOther.sentinel); + return *this; + } + ~LinkedList() { MOZ_ASSERT(isEmpty(), "failing this assertion means this LinkedList's creator is " diff --git a/mfbt/Sprintf.h b/mfbt/Sprintf.h index 39a9ec1317eb..e0be271e5d5c 100644 --- a/mfbt/Sprintf.h +++ b/mfbt/Sprintf.h @@ -13,6 +13,7 @@ #include #include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" #ifdef __cplusplus @@ -26,9 +27,7 @@ int VsprintfLiteral(char (&buffer)[N], const char* format, va_list args) } template -#if defined(__GNUC__) - __attribute__((format(printf, 2, 3))) -#endif +MOZ_FORMAT_PRINTF(2, 3) int SprintfLiteral(char (&buffer)[N], const char* format, ...) { va_list args; diff --git a/mfbt/tests/TestLinkedList.cpp b/mfbt/tests/TestLinkedList.cpp index 55db35517cbd..519b34c56636 100644 --- a/mfbt/tests/TestLinkedList.cpp +++ b/mfbt/tests/TestLinkedList.cpp @@ -12,7 +12,7 @@ using mozilla::LinkedListElement; struct SomeClass : public LinkedListElement { unsigned int mValue; - explicit SomeClass(int aValue) : mValue(aValue) {} + explicit SomeClass(int aValue = 0) : mValue(aValue) {} void incr() { ++mValue; } }; @@ -34,7 +34,7 @@ TestList() LinkedList list; SomeClass one(1), two(2), three(3); - + MOZ_RELEASE_ASSERT(list.isEmpty()); MOZ_RELEASE_ASSERT(!list.getFirst()); MOZ_RELEASE_ASSERT(!list.getLast()); @@ -52,7 +52,7 @@ TestList() MOZ_RELEASE_ASSERT(one.isInList()); MOZ_RELEASE_ASSERT(!two.isInList()); MOZ_RELEASE_ASSERT(!three.isInList()); - + MOZ_RELEASE_ASSERT(!list.isEmpty()); MOZ_RELEASE_ASSERT(list.getFirst()->mValue == 1); MOZ_RELEASE_ASSERT(list.getLast()->mValue == 1); @@ -117,6 +117,45 @@ TestList() MOZ_RELEASE_ASSERT(list.getLast()->mValue == 4); } +static void +TestMove() +{ + auto MakeSomeClass = + [] (unsigned int aValue) -> SomeClass { return SomeClass(aValue); }; + + LinkedList list1; + + // Test move constructor for LinkedListElement. + SomeClass c1(MakeSomeClass(1)); + list1.insertBack(&c1); + + // Test move assignment for LinkedListElement from an element not in a + // list. + SomeClass c2; + c2 = MakeSomeClass(2); + list1.insertBack(&c2); + + // Test move assignment of LinkedListElement from an element already in a + // list. + SomeClass c3; + c3 = Move(c2); + MOZ_RELEASE_ASSERT(!c2.isInList()); + MOZ_RELEASE_ASSERT(c3.isInList()); + + // Test move constructor for LinkedList. + LinkedList list2(Move(list1)); + { unsigned int check[] { 1, 2 }; CheckListValues(list2, check); } + MOZ_RELEASE_ASSERT(list1.isEmpty()); + + // Test move assignment for LinkedList. + LinkedList list3; + list3 = Move(list2); + { unsigned int check[] { 1, 2 }; CheckListValues(list3, check); } + MOZ_RELEASE_ASSERT(list2.isEmpty()); + + list3.clear(); +} + struct PrivateClass : private LinkedListElement { friend class mozilla::LinkedList; friend class mozilla::LinkedListElement; @@ -143,5 +182,6 @@ main() { TestList(); TestPrivate(); + TestMove(); return 0; } diff --git a/moz.configure b/moz.configure index 58bc27be5c38..43a0503b3879 100644 --- a/moz.configure +++ b/moz.configure @@ -316,7 +316,9 @@ def nsis_version(nsis): raise FatalCheckError('Unknown version of makensis') ver = Version(m.group(0)) - if ver < nsis_min_version: + # Versions comparisons don't quite work well with beta versions, so ensure + # it works for the non-beta version. + if ver < nsis_min_version and (ver >= '3.0a' or ver < '3'): raise FatalCheckError('To build the installer you must have NSIS' ' version %s or greater in your path' % nsis_min_version) diff --git a/python/mozbuild/mozbuild/test/configure/test_moz_configure.py b/python/mozbuild/mozbuild/test/configure/test_moz_configure.py index 440191c6d7ea..7c318adefd0b 100644 --- a/python/mozbuild/mozbuild/test/configure/test_moz_configure.py +++ b/python/mozbuild/mozbuild/test/configure/test_moz_configure.py @@ -57,6 +57,37 @@ class TestMozConfigure(BaseConfigureTest): get_value_for(['--enable-application=browser', '--with-foo=foo bar'])) + def test_nsis_version(self): + this = self + + class FakeNSIS(object): + def __init__(self, version): + self.version = version + + def __call__(self, stdin, args): + this.assertEquals(args, ('-version',)) + return 0, self.version, '' + + def check_nsis_version(version): + sandbox = self.get_sandbox( + {'/usr/bin/makensis': FakeNSIS(version)}, {}, [], + {'PATH': '/usr/bin', 'MAKENSISU': '/usr/bin/makensis'}) + return sandbox._value_for(sandbox['nsis_version']) + + with self.assertRaises(SystemExit) as e: + check_nsis_version('v2.5') + + with self.assertRaises(SystemExit) as e: + check_nsis_version('v3.0a2') + + self.assertEquals(check_nsis_version('v3.0b1'), '3.0b1') + self.assertEquals(check_nsis_version('v3.0b2'), '3.0b2') + self.assertEquals(check_nsis_version('v3.0rc1'), '3.0rc1') + self.assertEquals(check_nsis_version('v3.0'), '3.0') + self.assertEquals(check_nsis_version('v3.0-2'), '3.0') + self.assertEquals(check_nsis_version('v3.0.1'), '3.0') + self.assertEquals(check_nsis_version('v3.1'), '3.1') + if __name__ == '__main__': main() diff --git a/security/manager/locales/en-US/chrome/pippki/pippki.properties b/security/manager/locales/en-US/chrome/pippki/pippki.properties index fe7bc2e0797e..056f609af1fd 100644 --- a/security/manager/locales/en-US/chrome/pippki/pippki.properties +++ b/security/manager/locales/en-US/chrome/pippki/pippki.properties @@ -111,7 +111,9 @@ pageInfo_MixedContent2=Parts of the page you are viewing were not encrypted befo pageInfo_WeakCipher=Your connection to this website uses weak encryption and is not private. Other people can view your information or modify the website’s behavior. # Cert Viewer -certDetails=Certificate Viewer: +# LOCALIZATION NOTE(certViewerTitle): Title used for the Certificate Viewer. +# %1$S is a string representative of the certificate being viewed. +certViewerTitle=Certificate Viewer: “%1$S” notPresent= # Token Manager diff --git a/security/manager/pki/nsNSSDialogHelper.h b/security/manager/pki/nsNSSDialogHelper.h index d35646ee9793..87605da5f1d3 100644 --- a/security/manager/pki/nsNSSDialogHelper.h +++ b/security/manager/pki/nsNSSDialogHelper.h @@ -11,17 +11,28 @@ class mozIDOMWindowProxy; class nsISupports; /** - * Common class that uses the window watcher service to open a - * standard dialog, with or without a parent context. The params - * parameter can be an nsISupportsArray so any number of additional - * arguments can be used. + * Helper class that uses the window watcher service to open a standard dialog, + * with or without a parent context. */ class nsNSSDialogHelper { public: - // params is a nsIDialogParamBlock or a nsIKeygenThread + /** + * Opens a XUL dialog. + * + * @param window + * Parent window of the dialog, or nullptr to signal no parent. + * @param url + * URL to the XUL dialog. + * @param params + * Parameters to pass to the dialog. Same semantics as the + * nsIWindowWatcher.openWindow() |aArguments| parameter. + * @param modal + * true if the dialog should be modal, false otherwise. + * @return The result of opening the dialog. + */ static nsresult openDialog(mozIDOMWindowProxy* window, const char* url, nsISupports* params, bool modal = true); }; -#endif +#endif // nsNSSDialogHelper_h diff --git a/security/manager/pki/nsNSSDialogs.cpp b/security/manager/pki/nsNSSDialogs.cpp index fa9bc41e3707..1e80cc4d285c 100644 --- a/security/manager/pki/nsNSSDialogs.cpp +++ b/security/manager/pki/nsNSSDialogs.cpp @@ -7,35 +7,28 @@ /* * Dialog services for PIP. */ + +#include "nsNSSDialogs.h" + #include "mozIDOMWindow.h" #include "mozilla/Assertions.h" #include "mozilla/Casting.h" #include "nsArray.h" -#include "nsDateTimeFormatCID.h" #include "nsEmbedCID.h" -#include "nsIComponentManager.h" -#include "nsIDateTimeFormat.h" #include "nsIDialogParamBlock.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIKeygenThread.h" #include "nsIPromptService.h" #include "nsIProtectedAuthThread.h" -#include "nsIServiceManager.h" #include "nsIWindowWatcher.h" #include "nsIX509CertDB.h" #include "nsIX509Cert.h" -#include "nsIX509CertValidity.h" #include "nsNSSDialogHelper.h" -#include "nsNSSDialogs.h" -#include "nsPromiseFlatString.h" -#include "nsReadableUtils.h" #include "nsString.h" #define PIPSTRING_BUNDLE_URL "chrome://pippki/locale/pippki.properties" -/* ==== */ - nsNSSDialogs::nsNSSDialogs() { } @@ -329,33 +322,18 @@ nsNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor* ctx, return NS_OK; } -NS_IMETHODIMP +NS_IMETHODIMP nsNSSDialogs::ViewCert(nsIInterfaceRequestor* ctx, nsIX509Cert* cert) { - nsCOMPtr dlgArray = nsArrayBase::Create(); - if (!dlgArray) { - return NS_ERROR_FAILURE; - } - nsresult rv = dlgArray->AppendElement(cert, false); - if (NS_FAILED(rv)) { - return rv; - } - nsCOMPtr dlgParamBlock( - do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID)); - if (!dlgParamBlock) { - return NS_ERROR_FAILURE; - } - rv = dlgParamBlock->SetObjects(dlgArray); - if (NS_FAILED(rv)) { - return rv; - } + // |ctx| is allowed to be null. + NS_ENSURE_ARG(cert); // Get the parent window for the dialog nsCOMPtr parent = do_GetInterface(ctx); return nsNSSDialogHelper::openDialog(parent, "chrome://pippki/content/certViewer.xul", - dlgParamBlock, - false); + cert, + false /*modal*/); } NS_IMETHODIMP diff --git a/security/manager/pki/resources/content/viewCertDetails.js b/security/manager/pki/resources/content/certViewer.js similarity index 95% rename from security/manager/pki/resources/content/viewCertDetails.js rename to security/manager/pki/resources/content/certViewer.js index 5a5650a1ebd9..c625076943cf 100644 --- a/security/manager/pki/resources/content/viewCertDetails.js +++ b/security/manager/pki/resources/content/certViewer.js @@ -3,6 +3,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; +/** + * @file Implements functionality for certViewer.xul and its tabs certDump.xul + * and viewCertDetails.xul: a dialog that allows various attributes of a + * certificate to be viewed. + * @argument {nsISupports} window.arguments[0] + * The cert to view, queryable to nsIX509Cert. + */ + const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; const { Services } = Cu.import("resource://gre/modules/Services.jsm", {}); @@ -16,7 +24,6 @@ const nsIASN1Sequence = Ci.nsIASN1Sequence; const nsIASN1PrintableItem = Ci.nsIASN1PrintableItem; const nsIASN1Tree = Ci.nsIASN1Tree; const nsASN1Tree = "@mozilla.org/security/nsASN1Tree;1"; -const nsIDialogParamBlock = Ci.nsIDialogParamBlock; var bundle; @@ -71,21 +78,11 @@ function AddUsage(usage) function setWindowName() { - // Get the cert from the cert database - var certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB); - var myName = self.name; bundle = document.getElementById("pippki_bundle"); - var cert; - var certDetails = bundle.getString('certDetails'); - if (myName != "") { - document.title = certDetails + '"' + myName + '"'; // XXX l10n? - cert = certdb.findCertByNickname(myName); - } else { - var params = window.arguments[0].QueryInterface(nsIDialogParamBlock); - cert = params.objects.queryElementAt(0, nsIX509Cert); - document.title = certDetails + '"' + cert.windowTitle + '"'; // XXX l10n? - } + let cert = window.arguments[0].QueryInterface(Ci.nsIX509Cert); + document.title = bundle.getFormattedString("certViewerTitle", + [cert.windowTitle]); // // Set the cert attributes for viewing diff --git a/security/manager/pki/resources/content/certViewer.xul b/security/manager/pki/resources/content/certViewer.xul index e9a1e2b77fcc..3f2cd3bde04f 100644 --- a/security/manager/pki/resources/content/certViewer.xul +++ b/security/manager/pki/resources/content/certViewer.xul @@ -20,7 +20,8 @@ - + + + + + + + + + + diff --git a/toolkit/components/url-classifier/ProtocolParser.cpp b/toolkit/components/url-classifier/ProtocolParser.cpp index 55060f00c0e5..35a3edea7774 100644 --- a/toolkit/components/url-classifier/ProtocolParser.cpp +++ b/toolkit/components/url-classifier/ProtocolParser.cpp @@ -69,6 +69,7 @@ ParseChunkRange(nsACString::const_iterator& aBegin, ProtocolParser::ProtocolParser() : mUpdateStatus(NS_OK) + , mUpdateWaitSec(0) { } @@ -116,7 +117,6 @@ ProtocolParser::GetTableUpdate(const nsACString& aTable) ProtocolParserV2::ProtocolParserV2() : mState(PROTOCOL_STATE_CONTROL) - , mUpdateWait(0) , mResetRequested(false) , mTableUpdate(nullptr) { @@ -180,8 +180,8 @@ ProtocolParserV2::ProcessControl(bool* aDone) // Set the table name from the table header line. SetCurrentTable(Substring(line, 2)); } else if (StringBeginsWith(line, NS_LITERAL_CSTRING("n:"))) { - if (PR_sscanf(line.get(), "n:%d", &mUpdateWait) != 1) { - PARSER_LOG(("Error parsing n: '%s' (%d)", line.get(), mUpdateWait)); + if (PR_sscanf(line.get(), "n:%d", &mUpdateWaitSec) != 1) { + PARSER_LOG(("Error parsing n: '%s' (%d)", line.get(), mUpdateWaitSec)); return NS_ERROR_FAILURE; } } else if (line.EqualsLiteral("r:pleasereset")) { @@ -771,6 +771,10 @@ ProtocolParserProtobuf::End() return; } + auto minWaitDuration = response.minimum_wait_duration(); + mUpdateWaitSec = minWaitDuration.seconds() + + minWaitDuration.nanos() / 1000000000; + for (int i = 0; i < response.list_update_responses_size(); i++) { auto r = response.list_update_responses(i); nsresult rv = ProcessOneResponse(r); diff --git a/toolkit/components/url-classifier/ProtocolParser.h b/toolkit/components/url-classifier/ProtocolParser.h index e2b80375779c..351612cb3076 100644 --- a/toolkit/components/url-classifier/ProtocolParser.h +++ b/toolkit/components/url-classifier/ProtocolParser.h @@ -40,6 +40,8 @@ public: nsresult Begin(); virtual nsresult AppendStream(const nsACString& aData) = 0; + uint32_t UpdateWaitSec() { return mUpdateWaitSec; } + // Notify that the inbound data is ready for parsing if progressive // parsing is not supported, for example in V4. virtual void End() = 0; @@ -52,10 +54,9 @@ public: // These are only meaningful to V2. Since they were originally public, // moving them to ProtocolParserV2 requires a dymamic cast in the call - // sites. As a result, we will leave them until we remove support + // sites. As a result, we will leave them until we remove support // for V2 entirely.. virtual const nsTArray &Forwards() const { return mForwards; } - virtual int32_t UpdateWait() { return 0; } virtual bool ResetRequested() { return false; } protected: @@ -73,6 +74,9 @@ protected: // The table names that were requested from the client. nsTArray mRequestedTables; + // How long we should wait until the next update. + uint32_t mUpdateWaitSec; + private: void CleanupUpdates(); }; @@ -91,7 +95,6 @@ public: // Update information. virtual const nsTArray &Forwards() const override { return mForwards; } - virtual int32_t UpdateWait() override { return mUpdateWait; } virtual bool ResetRequested() override { return mResetRequested; } private: @@ -147,7 +150,6 @@ private: }; ChunkState mChunkState; - uint32_t mUpdateWait; bool mResetRequested; // Updates to apply to the current table being parsed. diff --git a/toolkit/components/url-classifier/content/listmanager.js b/toolkit/components/url-classifier/content/listmanager.js index d55d03c6e2f8..68325bec8fca 100644 --- a/toolkit/components/url-classifier/content/listmanager.js +++ b/toolkit/components/url-classifier/content/listmanager.js @@ -204,7 +204,7 @@ PROT_ListManager.prototype.kickoffUpdate_ = function (onDiskTableData) for (var updateUrl in this.needsUpdate_) { // If we haven't already kicked off updates for this updateUrl, set a // non-repeating timer for it. The timer delay will be reset either on - // updateSuccess to this.updateinterval, or backed off on downloadError. + // updateSuccess to this.updateInterval, or backed off on downloadError. // Don't set the updateChecker unless at least one table has updates // enabled. if (this.updatesNeeded_(updateUrl) && !this.updateCheckers_[updateUrl]) { @@ -492,12 +492,15 @@ PROT_ListManager.prototype.makeUpdateRequestForEntry_ = function(updateUrl, * wait before requesting again. */ PROT_ListManager.prototype.updateSuccess_ = function(tableList, updateUrl, - waitForUpdate) { + waitForUpdateSec) { log("update success for " + tableList + " from " + updateUrl + ": " + - waitForUpdate + "\n"); + waitForUpdateSec + "\n"); + + // The time unit below are all milliseconds if not specified. + var delay = 0; - if (waitForUpdate) { - delay = parseInt(waitForUpdate, 10) * 1000; + if (waitForUpdateSec) { + delay = parseInt(waitForUpdateSec, 10) * 1000; } // As long as the delay is something sane (5 min to 1 day), update // our delay time for requesting updates. We always use a non-repeating @@ -556,7 +559,7 @@ PROT_ListManager.prototype.updateSuccess_ = function(tableList, updateUrl, PROT_ListManager.prototype.updateError_ = function(table, updateUrl, result) { log("update error for " + table + " from " + updateUrl + ": " + result + "\n"); // There was some trouble applying the updates. Don't try again for at least - // updateInterval seconds. + // updateInterval milliseconds. this.updateCheckers_[updateUrl] = new G_Alarm(BindToObject(this.checkForUpdates, this, updateUrl), this.updateInterval, false); diff --git a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp index c74861b7bab7..50afd4369d1d 100644 --- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp +++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp @@ -392,7 +392,7 @@ void nsUrlClassifierDBServiceWorker::ResetUpdate() { LOG(("ResetUpdate")); - mUpdateWait = 0; + mUpdateWaitSec = 0; mUpdateStatus = NS_OK; mUpdateObserver = nullptr; } @@ -543,8 +543,8 @@ nsUrlClassifierDBServiceWorker::FinishStream() mProtocolParser->End(); if (NS_SUCCEEDED(mProtocolParser->Status())) { - if (mProtocolParser->UpdateWait()) { - mUpdateWait = mProtocolParser->UpdateWait(); + if (mProtocolParser->UpdateWaitSec()) { + mUpdateWaitSec = mProtocolParser->UpdateWaitSec(); } // XXX: Only allow forwards from the initial update? const nsTArray &forwards = @@ -592,8 +592,8 @@ nsUrlClassifierDBServiceWorker::FinishUpdate() mMissCache.Clear(); if (NS_SUCCEEDED(mUpdateStatus)) { - LOG(("Notifying success: %d", mUpdateWait)); - mUpdateObserver->UpdateSuccess(mUpdateWait); + LOG(("Notifying success: %d", mUpdateWaitSec)); + mUpdateObserver->UpdateSuccess(mUpdateWaitSec); } else if (NS_ERROR_NOT_IMPLEMENTED == mUpdateStatus) { LOG(("Treating NS_ERROR_NOT_IMPLEMENTED a successful update " "but still mark it spoiled.")); diff --git a/toolkit/components/url-classifier/nsUrlClassifierDBService.h b/toolkit/components/url-classifier/nsUrlClassifierDBService.h index 23288d659404..867141162e0e 100644 --- a/toolkit/components/url-classifier/nsUrlClassifierDBService.h +++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.h @@ -217,7 +217,7 @@ private: // storing a series of updates. nsTArray mTableUpdates; - int32_t mUpdateWait; + uint32_t mUpdateWaitSec; // Entries that cannot be completed. We expect them to die at // the next update diff --git a/toolkit/components/url-classifier/tests/gtest/TestProtocolParser.cpp b/toolkit/components/url-classifier/tests/gtest/TestProtocolParser.cpp new file mode 100644 index 000000000000..543588fa1da2 --- /dev/null +++ b/toolkit/components/url-classifier/tests/gtest/TestProtocolParser.cpp @@ -0,0 +1,87 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +#include "gtest/gtest.h" +#include "ProtocolParser.h" +#include "mozilla/EndianUtils.h" + +using namespace mozilla; +using namespace mozilla::safebrowsing; + +typedef FetchThreatListUpdatesResponse_ListUpdateResponse ListUpdateResponse; + +static void +InitUpdateResponse(ListUpdateResponse* aUpdateResponse, + ThreatType aThreatType, + const nsACString& aState, + const nsACString& aChecksum, + bool isFullUpdate, + const nsTArray& aFixedLengthPrefixes); + +static void +DumpBinary(const nsACString& aBinary); + +TEST(ProtocolParser, UpdateWait) +{ + // Top level response which contains a list of update response + // for different lists. + FetchThreatListUpdatesResponse response; + + auto r = response.mutable_list_update_responses()->Add(); + InitUpdateResponse(r, SOCIAL_ENGINEERING_PUBLIC, + nsCString("sta\x00te", 6), + nsCString("check\x0sum", 9), + true, + {0, 1, 2, 3}); + + // Set min wait duration. + auto minWaitDuration = response.mutable_minimum_wait_duration(); + minWaitDuration->set_seconds(8); + minWaitDuration->set_nanos(1 * 1000000000); + + std::string s; + response.SerializeToString(&s); + + DumpBinary(nsCString(s.c_str(), s.length())); + + ProtocolParser* p = new ProtocolParserProtobuf(); + p->AppendStream(nsCString(s.c_str(), s.length())); + p->End(); + ASSERT_EQ(p->UpdateWaitSec(), 9u); + delete p; +} + +static void +InitUpdateResponse(ListUpdateResponse* aUpdateResponse, + ThreatType aThreatType, + const nsACString& aState, + const nsACString& aChecksum, + bool isFullUpdate, + const nsTArray& aFixedLengthPrefixes) +{ + aUpdateResponse->set_threat_type(aThreatType); + aUpdateResponse->set_new_client_state(aState.BeginReading(), aState.Length()); + aUpdateResponse->mutable_checksum()->set_sha256(aChecksum.BeginReading(), aChecksum.Length()); + aUpdateResponse->set_response_type(isFullUpdate ? ListUpdateResponse::FULL_UPDATE + : ListUpdateResponse::PARTIAL_UPDATE); + + auto additions = aUpdateResponse->mutable_additions()->Add(); + additions->set_compression_type(RAW); + auto rawHashes = additions->mutable_raw_hashes(); + rawHashes->set_prefix_size(4); + auto prefixes = rawHashes->mutable_raw_hashes(); + for (auto p : aFixedLengthPrefixes) { + char buffer[4]; + NativeEndian::copyAndSwapToBigEndian(buffer, &p, 1); + prefixes->append(buffer, 4); + } +} + +static void DumpBinary(const nsACString& aBinary) +{ + nsCString s; + for (size_t i = 0; i < aBinary.Length(); i++) { + s.AppendPrintf("\\x%.2X", (uint8_t)aBinary[i]); + } + printf("%s\n", s.get()); +} \ No newline at end of file diff --git a/toolkit/components/url-classifier/tests/gtest/moz.build b/toolkit/components/url-classifier/tests/gtest/moz.build index fb641d70a613..68fdf7846073 100644 --- a/toolkit/components/url-classifier/tests/gtest/moz.build +++ b/toolkit/components/url-classifier/tests/gtest/moz.build @@ -11,6 +11,7 @@ LOCAL_INCLUDES += [ UNIFIED_SOURCES += [ 'TestChunkSet.cpp', 'TestPerProviderDirectory.cpp', + 'TestProtocolParser.cpp', 'TestRiceDeltaDecoder.cpp', 'TestSafebrowsingHash.cpp', 'TestSafeBrowsingProtobuf.cpp', diff --git a/xpcom/base/nscore.h b/xpcom/base/nscore.h index 14c12cdddd09..f6e73c6bc70c 100644 --- a/xpcom/base/nscore.h +++ b/xpcom/base/nscore.h @@ -159,16 +159,6 @@ # define MOZ_DEPRECATED #endif -/** - * Printf style formats - */ -#ifdef __GNUC__ -#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) \ - __attribute__ ((format (printf, stringIndex, firstToCheck))) -#else -#define MOZ_FORMAT_PRINTF(stringIndex, firstToCheck) -#endif - /** * Generic API modifiers which return the standard XPCOM nsresult type *