[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [Git][tpo/applications/tor-browser][tor-browser-140.15.0esr-15.0-1] 12 commits: Bug 2039206 - Wire WindowDevicePixelRatio to image-set....



Title: GitLab

ma1 pushed to branch tor-browser-140.15.0esr-15.0-1 at The Tor Project / Applications / Tor Browser

Commits:

  • 56736106
    by Pier Angelo Vendrame at 2026-09-01T12:40:48+02:00
    Bug 2039206 - Wire WindowDevicePixelRatio to image-set. r=firefox-style-system-reviewers,emilio,layout-reviewers
    
    Differential Revision: https://phabricator.services.mozilla.com/D300449
    
  • 71ecc1ad
    by Yury Delendik at 2026-09-01T12:40:53+02:00
    Bug 2045435 - Prune dying entries from wasm::Realm::instances_ during sweeping. r=jpages
    
    wasm::Realm::instances_ is a weak list. Readers rely on the
    instances()[i]->object() read barrier, but that barrier is a no-op once the
    owning zone is being incrementally swept, and entries are otherwise only
    removed at Instance finalization (~Instance -> unregisterInstance). So between
    marking a zone's instance objects dead and finalizing them, the list could
    still hand an about-to-be-finalized instance to a reader.
    
    Prune such entries at the start of zone sweeping via a new
    wasm::Realm::traceWeakInstances(), called from beginSweepingSweepGroup
    alongside the other per-realm weak-collection sweeps. This makes instances_
    behave like the engine's other weak collections, so it never exposes an
    about-to-be-finalized instance to the mutator during sweep slices.
    
    Differential Revision: https://phabricator.services.mozilla.com/D314032
    
  • b5de5efc
    by Gela at 2026-09-01T12:40:58+02:00
    Bug 2053320 - Part 1: Don't tie Nimbus tooling to `HomeActivity` UI  a=RyanVM
    
    Original Revision: https://phabricator.services.mozilla.com/D319628
    
    Differential Revision: https://phabricator.services.mozilla.com/D320784
    
  • 0b475830
    by Ting-Yu Lin at 2026-09-01T12:41:02+02:00
    Bug 2053578 - Use static_cast in nsSplittableFrame::UpdateFirstContinuationAndFirstInFlowCache(). r=layout-reviewers,jfkthame
    
    `nsSplittableFrame` is a subclass of `nsIFrame`, it is sufficient to use
    `static_cast`.
    
    Differential Revision: https://phabricator.services.mozilla.com/D315157
    
  • 2c620a58
    by Ting-Yu Lin at 2026-09-01T12:41:07+02:00
    Bug 2053578 - Update first-in-flow cache when a continuation is changing from fluid to non-fluid. r=layout-reviewers,jfkthame
    
    The original case in bug 2053578 comment 5 can reproduce an ASAN
    use-after-poison with the patch bug 2053578 comment 6 applied. However, with
    unpatched code, the best we can do is using a DEBUG-only assertion to catch the
    error condition that detect a stale first-in-flow cache in next-in-flow.
    
    `bidi-inline-continuation-first-in-flow.html` is generated with the help of
    Claude code, and it can trigger the assertion without other fix in this patch.
    
    Differential Revision: https://phabricator.services.mozilla.com/D315158
    
  • f14f9f44
    by Jan Grulich at 2026-09-01T12:41:11+02:00
    Bug 2054625 - WebRTC backport: Video capture: validate PipeWire camera frame size to prevent OOB read r=pehrsons
    
    Check spa_chunk::size is not larger than mmap'ed buffer, which would
    lead to an out-of-bounds read when the frame is copied. Validate that
    chunk offset + size does not exceed maxsize before processing.
    
    This is a simple backport of an WebRTC upstream change.
    
    Upstream commit: 612430e8266881eaff478b0000cacc90fb71c918
    
    Differential Revision: https://phabricator.services.mozilla.com/D316000
    
  • 6017bf80
    by David Parks at 2026-09-01T12:41:16+02:00
    Bug 2058006 - Call Destroy() unconditionally in ~StatusBarEntry.  a=RyanVM DONTBUILD
    
    Allow Destroy() to tear down mIconLoader, even if Init() does not successfully
    complete initialization.
    
    Original Revision: https://phabricator.services.mozilla.com/D318206
    
    Differential Revision: https://phabricator.services.mozilla.com/D319879
    
  • 9cf002cf
    by David Parks at 2026-09-01T12:41:20+02:00
    Bug 2058013 - Only resolve non-filesystem picker results as shell libraries  a=RyanVM DONTBUILD
    
    A genuine shell library is a virtual item with no filesystem path.  A
    .library-ms file is an ordinary file whose XML can name any local directory.
    
    filedialog::GetFolderResults was passing whatever IFileDialog::GetResult
    returned to IShellLibrary::LoadLibraryFromItem and, on success, replacing it
    with the library's embedded default save folder.
    
    Gating the resolution on the item being affirmatively not a filesystem object
    keeps real libraries selectable and resolving as before, while a .library-ms
    file "resolves" to itself -- the .library-ms file, not its target.
    
    Original Revision: https://phabricator.services.mozilla.com/D318246
    
    Differential Revision: https://phabricator.services.mozilla.com/D319957
    
  • 1cec2a2f
    by Iain Ireland at 2026-09-01T12:41:25+02:00
    Bug 2058626: Check for mutually exclusive flags when deserializing cloned RegExp r=spidermonkey-reviewers,jonco
    
    Differential Revision: https://phabricator.services.mozilla.com/D316904
    
  • 08795680
    by Kui-Feng Lee at 2026-09-01T12:41:30+02:00
    Bug 2058661 - Clear the drag source window's GdkDragContext pointer synchronously. r=stransky a=RyanVM DONTBUILD
    
    gtk_drag_begin_with_coordinates() returns a borrowed context: GtkDragSourceInfo
    holds the only reference, and gtk_drag_source_info_destroy() drops it as soon as
    the drag-end handler returns. nsWindow::mSourceDragContext was cleared only from
    an async runnable (EndDragSessionMainThread -> EndDragSessionImpl), so between
    GTK's unref and that runnable the pointer dangled, and nsWindow::OnUnmap() calls
    gtk_drag_cancel() on it. Content can land an unmap in that window with a
    window.close() task queued before the drag ended.
    
    EndDragSessionImpl keeps its own clear for drags torn down without a drag-end.
    
    Original Revision: https://phabricator.services.mozilla.com/D315509
    
    Differential Revision: https://phabricator.services.mozilla.com/D319278
    
  • 2f953af5
    by Kershaw Chang at 2026-09-01T12:41:34+02:00
    Bug 2059199 - Reject NUL bytes in chunked trailer and chunk-size lines  a=RyanVM DONTBUILD
    
    A trailer field line whose first byte is NUL would look empty to the
    end-of-trailer check, ending the trailer section early. We would then stop
    reading the body before the server (or a shared proxy) does, and disagree
    with them about where the response ends.
    
    Original Revision: https://phabricator.services.mozilla.com/D317742
    
    Differential Revision: https://phabricator.services.mozilla.com/D319931
    
  • 553036bc
    by Sotaro Ikeda at 2026-09-01T12:41:39+02:00
    Bug 2061532  a=RyanVM DONTBUILD
    
    ANGLE Metal backend usage is also going to disable RenderExternalTextureHost usage.
    
    Original Revision: https://phabricator.services.mozilla.com/D318624
    
    Differential Revision: https://phabricator.services.mozilla.com/D320769
    

24 changed files:

Changes:

  • dom/base/ResponsiveImageSelector.cpp
    ... ... @@ -351,10 +351,6 @@ bool ResponsiveImageSelector::SelectImage(bool aReselect) {
    351 351
       if (overrideDPPX > 0) {
    
    352 352
         displayDensity = overrideDPPX;
    
    353 353
       }
    
    354
    -  if (doc->ShouldResistFingerprinting(RFPTarget::WindowDevicePixelRatio)) {
    
    355
    -    displayDensity =
    
    356
    -        nsRFPService::GetDevicePixelRatioAtZoom(pctx->GetFullZoom());
    
    357
    -  }
    
    358 354
     
    
    359 355
       // Per spec, "In a UA-specific manner, choose one image source"
    
    360 356
       // - For now, select the lowest density greater than displayDensity, otherwise
    

  • gfx/webrender_bindings/RenderExternalTextureHost.cpp
    ... ... @@ -126,7 +126,14 @@ bool RenderExternalTextureHost::IsReadyForDeletion() {
    126 126
     
    
    127 127
       auto& textureSource = mTextureSources[0];
    
    128 128
       if (textureSource) {
    
    129
    -    return textureSource->Sync(false);
    
    129
    +    if (textureSource->Sync(/* aBlocking */ true)) {
    
    130
    +      return true;
    
    131
    +    }
    
    132
    +    if (mGL && mGL->MakeCurrent() && !mGL->IsDestroyed()) {
    
    133
    +      mGL->fFinish();
    
    134
    +      return true;
    
    135
    +    }
    
    136
    +    return false;
    
    130 137
       }
    
    131 138
     
    
    132 139
       return true;
    
    ... ... @@ -153,7 +160,11 @@ wr::WrExternalImage RenderExternalTextureHost::Lock(uint8_t aChannelIndex,
    153 160
     
    
    154 161
     void RenderExternalTextureHost::PrepareForUse() { mTextureUpdateNeeded = true; }
    
    155 162
     
    
    156
    -void RenderExternalTextureHost::Unlock() {}
    
    163
    +void RenderExternalTextureHost::Unlock() {
    
    164
    +  if (mInitialized && mTextureSources[0]) {
    
    165
    +    mTextureSources[0]->MaybeFenceTexture();
    
    166
    +  }
    
    167
    +}
    
    157 168
     
    
    158 169
     void RenderExternalTextureHost::UpdateTexture(size_t aIndex) {
    
    159 170
       MOZ_ASSERT(mSurfaces[aIndex]);
    

  • js/src/gc/GCRuntime.h
    ... ... @@ -924,6 +924,7 @@ class GCRuntime {
    924 924
       void updateAtomsBitmap();
    
    925 925
       void sweepCCWrappers();
    
    926 926
       void sweepRealmGlobals();
    
    927
    +  void sweepWasmInstances();
    
    927 928
       void sweepEmbeddingWeakPointers(JS::GCContext* gcx);
    
    928 929
       void sweepMisc();
    
    929 930
       void sweepCompressionTasks();
    

  • js/src/gc/Sweeping.cpp
    ... ... @@ -1396,6 +1396,13 @@ void GCRuntime::sweepRealmGlobals() {
    1396 1396
       }
    
    1397 1397
     }
    
    1398 1398
     
    
    1399
    +void GCRuntime::sweepWasmInstances() {
    
    1400
    +  for (SweepGroupRealmsIter r(this); !r.done(); r.next()) {
    
    1401
    +    AutoSetThreadIsSweeping threadIsSweeping(r->zone());
    
    1402
    +    r->wasm.traceWeakInstances();
    
    1403
    +  }
    
    1404
    +}
    
    1405
    +
    
    1399 1406
     void GCRuntime::sweepMisc() {
    
    1400 1407
       SweepingTracer trc(rt);
    
    1401 1408
       for (SweepGroupRealmsIter r(this); !r.done(); r.next()) {
    
    ... ... @@ -1709,6 +1716,11 @@ IncrementalProgress GCRuntime::beginSweepingSweepGroup(JS::GCContext* gcx,
    1709 1716
       // This must happen before updating embedding weak pointers.
    
    1710 1717
       sweepRealmGlobals();
    
    1711 1718
     
    
    1719
    +  // Prune dying wasm instances from each realm's weak instance list now, at the
    
    1720
    +  // start of sweeping, before the mutator can observe them via the (now no-op)
    
    1721
    +  // instances() read barrier during later incremental slices.
    
    1722
    +  sweepWasmInstances();
    
    1723
    +
    
    1712 1724
       sweepEmbeddingWeakPointers(gcx);
    
    1713 1725
     
    
    1714 1726
       {
    

  • js/src/jit-test/tests/structured-clone/bug2058626.js
    1
    +function forge(pattern, srcFlags, flagsByte) {
    
    2
    +  var cb = serialize(new RegExp(pattern, srcFlags), undefined, { scope: "DifferentProcess" });
    
    3
    +  var u8 = new Uint8Array(cb.arraybuffer);
    
    4
    +  for (var i = 0; i + 8 <= u8.length; i += 4) {
    
    5
    +    var tag = u8[i+4] | (u8[i+5] << 8) | (u8[i+6] << 16) | (u8[i+7] << 24);
    
    6
    +    if ((tag >>> 0) === 0xFFFF0006) { u8[i] = flagsByte; break; }
    
    7
    +  }
    
    8
    +  cb.clonebuffer = u8.buffer;
    
    9
    +  return deserialize(cb, { scope: "DifferentProcess" });
    
    10
    +}
    
    11
    +try {
    
    12
    +  var forged = forge("[\\q{abc|de}]", "v", 0x90);
    
    13
    +  var bad = new RegExp(forged, "u");
    
    14
    +  try { bad.exec("abc"); } catch {}
    
    15
    +  var good = new RegExp("[\\q{abc|de}]", "u");
    
    16
    +} catch {}

  • js/src/vm/StructuredClone.cpp
    ... ... @@ -3189,7 +3189,9 @@ bool JSStructuredCloneReader::startRead(MutableHandleValue vp,
    3189 3189
         }
    
    3190 3190
     
    
    3191 3191
         case SCTAG_REGEXP_OBJECT: {
    
    3192
    -      if ((data & RegExpFlag::AllFlags) != data) {
    
    3192
    +      // Reject invalid flags. /u and /v are mutually exclusive.
    
    3193
    +      if ((data & RegExpFlag::AllFlags) != data ||
    
    3194
    +          ((data & RegExpFlag::Unicode) && (data & RegExpFlag::UnicodeSets))) {
    
    3193 3195
             JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
    
    3194 3196
                                       JSMSG_SC_BAD_SERIALIZED_DATA, "regexp");
    
    3195 3197
             return false;
    

  • js/src/wasm/WasmRealm.cpp
    ... ... @@ -18,6 +18,7 @@
    18 18
     
    
    19 19
     #include "wasm/WasmRealm.h"
    
    20 20
     
    
    21
    +#include "gc/Marking.h"
    
    21 22
     #include "vm/GlobalObject.h"
    
    22 23
     #include "vm/Realm.h"
    
    23 24
     #include "wasm/WasmDebug.h"
    
    ... ... @@ -111,6 +112,19 @@ void wasm::Realm::unregisterInstance(Instance& instance) {
    111 112
       }
    
    112 113
     }
    
    113 114
     
    
    115
    +void wasm::Realm::traceWeakInstances() {
    
    116
    +  // Registration/unregistration of instances_ is tied to Instance lifetime, so
    
    117
    +  // an instance whose owning object is about to be finalized is still present
    
    118
    +  // here until ~Instance runs. Remove such entries now, at the start of zone
    
    119
    +  // sweeping, because the instances() read barrier that otherwise protects
    
    120
    +  // readers is a no-op once the zone is being swept. erase order is preserved,
    
    121
    +  // so the pointer-sorted invariant used by BinarySearchIf holds.
    
    122
    +  instances_.eraseIf([](Instance* instance) {
    
    123
    +    return js::gc::IsAboutToBeFinalizedUnbarriered(
    
    124
    +        instance->objectUnbarriered());
    
    125
    +  });
    
    126
    +}
    
    127
    +
    
    114 128
     void wasm::Realm::ensureProfilingLabels(bool profilingEnabled) {
    
    115 129
       for (Instance* instance : instances_) {
    
    116 130
         instance->ensureProfilingLabels(profilingEnabled);
    

  • js/src/wasm/WasmRealm.h
    ... ... @@ -53,10 +53,17 @@ class Realm {
    53 53
       // Return a vector of all live instances in the realm. The lifetime of
    
    54 54
       // these Instances is determined by their owning WasmInstanceObject.
    
    55 55
       // Note that accessing instances()[i]->object() triggers a read barrier
    
    56
    -  // since instances() is effectively a weak list.
    
    56
    +  // since instances() is effectively a weak list. This read barrier is only
    
    57
    +  // effective while the owning zone is being marked; traceWeakInstances()
    
    58
    +  // prunes dying entries at the start of sweeping so that the list never
    
    59
    +  // exposes an about-to-be-finalized instance to the mutator.
    
    57 60
     
    
    58 61
       const InstanceVector& instances() const { return instances_; }
    
    59 62
     
    
    63
    +  // Remove instances whose owning object is about to be finalized. Called at
    
    64
    +  // the start of zone sweeping, when the instances() read barrier is a no-op.
    
    65
    +  void traceWeakInstances();
    
    66
    +
    
    60 67
       // Ensure all Instances in this Realm have profiling labels created.
    
    61 68
     
    
    62 69
       void ensureProfilingLabels(bool profilingEnabled);
    

  • layout/base/nsPresContext.cpp
    ... ... @@ -978,7 +978,11 @@ void nsPresContext::RecomputeBrowsingContextDependentData() {
    978 978
         auto systemZoom = LookAndFeel::SystemZoomSettings();
    
    979 979
         SetFullZoom(browsingContext->FullZoom() * systemZoom.mFullZoom);
    
    980 980
         SetTextZoom(browsingContext->TextZoom() * systemZoom.mTextZoom);
    
    981
    -    SetOverrideDPPX(browsingContext->OverrideDPPX());
    
    981
    +    if (doc->ShouldResistFingerprinting(RFPTarget::WindowDevicePixelRatio)) {
    
    982
    +      SetOverrideDPPX(nsRFPService::GetDevicePixelRatioAtZoom(GetFullZoom()));
    
    983
    +    } else {
    
    984
    +      SetOverrideDPPX(browsingContext->OverrideDPPX());
    
    985
    +    }
    
    982 986
       }
    
    983 987
     
    
    984 988
       auto* top = browsingContext->Top();
    

  • layout/generic/nsSplittableFrame.cpp
    ... ... @@ -214,7 +214,7 @@ void nsSplittableFrame::UpdateFirstContinuationAndFirstInFlowCache() {
    214 214
         if (oldCachedFirstContinuation != newFirstContinuation) {
    
    215 215
           // Update the first-continuation cache for us and our next-continuations.
    
    216 216
           for (nsSplittableFrame* f = this; f;
    
    217
    -           f = reinterpret_cast<nsSplittableFrame*>(f->GetNextContinuation())) {
    
    217
    +           f = static_cast<nsSplittableFrame*>(f->GetNextContinuation())) {
    
    218 218
             f->mFirstContinuation = newFirstContinuation;
    
    219 219
           }
    
    220 220
         }
    
    ... ... @@ -227,7 +227,7 @@ void nsSplittableFrame::UpdateFirstContinuationAndFirstInFlowCache() {
    227 227
           // behavior when a frame list is destroyed from the front. To avoid that
    
    228 228
           // pathological behavior, we simply purge the cached values.
    
    229 229
           for (nsSplittableFrame* f = this; f;
    
    230
    -           f = reinterpret_cast<nsSplittableFrame*>(f->GetNextContinuation())) {
    
    230
    +           f = static_cast<nsSplittableFrame*>(f->GetNextContinuation())) {
    
    231 231
             f->mFirstContinuation = nullptr;
    
    232 232
           }
    
    233 233
         }
    
    ... ... @@ -239,22 +239,41 @@ void nsSplittableFrame::UpdateFirstContinuationAndFirstInFlowCache() {
    239 239
         if (oldCachedFirstInFlow != newFirstInFlow) {
    
    240 240
           // Update the first-in-flow cache for us and our next-in-flows.
    
    241 241
           for (nsSplittableFrame* f = this; f;
    
    242
    -           f = reinterpret_cast<nsSplittableFrame*>(f->GetNextInFlow())) {
    
    242
    +           f = static_cast<nsSplittableFrame*>(f->GetNextInFlow())) {
    
    243 243
             f->mFirstInFlow = newFirstInFlow;
    
    244 244
           }
    
    245 245
         }
    
    246 246
       } else {
    
    247
    -    // We become the new first-in-flow due to our prev-in-flow being removed.
    
    248
    -    if (oldCachedFirstInFlow) {
    
    249
    -      // It's tempting to update the first-in-flow cache for our
    
    250
    -      // next-in-flows here, but that would result in overall O(n^2)
    
    251
    -      // behavior when a frame list is destroyed from the front. To avoid that
    
    252
    -      // pathological behavior, we simply purge the cached values.
    
    247
    +    if (GetPrevContinuation()) {
    
    248
    +      // We become the new first-in-flow after changing from fluid to non-fluid.
    
    249
    +      // Update the stale first-in-flow cache for us and all next-in-flows.
    
    250
    +      //
    
    251
    +      // Note that this has no counterpart in the above mFirstContinuation cache
    
    252
    +      // since GetPrevContinuation() does not depend on the
    
    253
    +      // NS_FRAME_IS_FLUID_CONTINUATION bit.
    
    253 254
           for (nsSplittableFrame* f = this; f;
    
    254
    -           f = reinterpret_cast<nsSplittableFrame*>(f->GetNextInFlow())) {
    
    255
    -        f->mFirstInFlow = nullptr;
    
    255
    +           f = static_cast<nsSplittableFrame*>(f->GetNextInFlow())) {
    
    256
    +        f->mFirstInFlow = this;
    
    257
    +      }
    
    258
    +    } else {
    
    259
    +      // We become the new first-in-flow due to our prev-in-flow being removed.
    
    260
    +      if (oldCachedFirstInFlow) {
    
    261
    +        // It's tempting to update the first-in-flow cache for our
    
    262
    +        // next-in-flows here, but that would result in overall O(n^2)
    
    263
    +        // behavior when a frame list is destroyed from the front. To avoid that
    
    264
    +        // pathological behavior, we simply purge the cached values.
    
    265
    +        for (nsSplittableFrame* f = this; f;
    
    266
    +             f = static_cast<nsSplittableFrame*>(f->GetNextInFlow())) {
    
    267
    +          f->mFirstInFlow = nullptr;
    
    268
    +        }
    
    256 269
           }
    
    257 270
         }
    
    271
    +
    
    272
    +    DebugOnly<nsSplittableFrame*> nextInFlow =
    
    273
    +        static_cast<nsSplittableFrame*>(GetNextInFlow());
    
    274
    +    MOZ_ASSERT(!nextInFlow || !nextInFlow->mFirstInFlow ||
    
    275
    +                   nextInFlow->mFirstInFlow == this,
    
    276
    +               "Our next-in-flow caches a stale first-in-flow!");
    
    258 277
       }
    
    259 278
     }
    
    260 279
     
    

  • mobile/android/fenix/app/src/main/AndroidManifest.xml
    ... ... @@ -770,6 +770,16 @@
    770 770
                     android:value="androidx.startup"
    
    771 771
                     tools:node="remove" />
    
    772 772
             </provider>
    
    773
    +
    
    774
    +        <receiver
    
    775
    +          android:name="org.mozilla.fenix.experiments.QANimbusToolingReceiver"
    
    776
    +          android:exported="true"
    
    777
    +          android:enabled="true"
    
    778
    +          android:permission="android.permission.DUMP">
    
    779
    +          <intent-filter>
    
    780
    +            <action android:name="org.mozilla.fenix.NIMBUS_TOOLING" />
    
    781
    +          </intent-filter>
    
    782
    +        </receiver>
    
    773 783
         </application>
    
    774 784
     
    
    775 785
     </manifest>

  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
    ... ... @@ -89,7 +89,6 @@ import mozilla.components.support.utils.ext.getParcelableExtraCompat
    89 89
     import mozilla.components.support.utils.toSafeIntent
    
    90 90
     import mozilla.components.support.webextensions.WebExtensionPopupObserver
    
    91 91
     import mozilla.telemetry.glean.private.NoExtras
    
    92
    -import org.mozilla.experiments.nimbus.initializeTooling
    
    93 92
     import org.mozilla.fenix.GleanMetrics.AppIcon
    
    94 93
     import org.mozilla.fenix.GleanMetrics.Events
    
    95 94
     import org.mozilla.fenix.GleanMetrics.Metrics
    
    ... ... @@ -330,8 +329,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity, TorAn
    330 329
             // DO NOT MOVE ANYTHING ABOVE THIS getProfilerTime CALL.
    
    331 330
             val startTimeProfiler = components.core.engine.profiler?.getProfilerTime()
    
    332 331
     
    
    333
    -        // Setup nimbus-cli tooling. This is a NOOP when launching normally.
    
    334
    -        components.nimbus.sdk.initializeTooling(applicationContext, intent)
    
    335 332
             components.strictMode.attachListenerToDisablePenaltyDeath(supportFragmentManager)
    
    336 333
             MarkersFragmentLifecycleCallbacks.register(supportFragmentManager, components.core.engine)
    
    337 334
     
    

  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/experiments/QANimbusToolingReceiver.kt
    1
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    +
    
    5
    +package org.mozilla.fenix.experiments
    
    6
    +
    
    7
    +import android.content.BroadcastReceiver
    
    8
    +import android.content.Context
    
    9
    +import android.content.Intent
    
    10
    +import kotlinx.coroutines.CoroutineDispatcher
    
    11
    +import kotlinx.coroutines.CoroutineScope
    
    12
    +import kotlinx.coroutines.Dispatchers
    
    13
    +import kotlinx.coroutines.launch
    
    14
    +import mozilla.components.support.base.log.logger.Logger
    
    15
    +import org.mozilla.experiments.nimbus.initializeTooling
    
    16
    +import org.mozilla.fenix.ext.components
    
    17
    +
    
    18
    +private val logger = Logger("QANimbusToolingReceiver")
    
    19
    +
    
    20
    +/**
    
    21
    + * Receiver triggered on demand via `nimbus-cli` to manually enroll into Nimbus experiments.
    
    22
    + *
    
    23
    + * ```
    
    24
    + *   adb shell am broadcast -a org.mozilla.fenix.NIMBUS_TOOLING \
    
    25
    + *       -p org.mozilla.fenix
    
    26
    + * ```
    
    27
    + *
    
    28
    + * `-p org.mozilla.fenix` is the package name, so adjust that value for release/beta/nightly/debug.
    
    29
    + *
    
    30
    + * @param dispatcher the [CoroutineDispatcher] the tooling commands are applied on.
    
    31
    + */
    
    32
    +class QANimbusToolingReceiver(private val dispatcher: CoroutineDispatcher = Dispatchers.IO) : BroadcastReceiver() {
    
    33
    +    override fun onReceive(context: Context, intent: Intent) {
    
    34
    +        if (intent.action != ACTION_NIMBUS_TOOLING) return
    
    35
    +
    
    36
    +        logger.info("Enqueueing QANimbusToolingReceiver via debug trigger")
    
    37
    +
    
    38
    +        val applicationContext = context.applicationContext
    
    39
    +
    
    40
    +        val pendingResult: PendingResult? = goAsync()
    
    41
    +        CoroutineScope(dispatcher).launch {
    
    42
    +            try {
    
    43
    +                applicationContext.components.nimbus.sdk.initializeTooling(
    
    44
    +                    applicationContext,
    
    45
    +                    intent,
    
    46
    +                )
    
    47
    +            } finally {
    
    48
    +                logger.info("Nimbus tooling command processed")
    
    49
    +                pendingResult?.finish()
    
    50
    +            }
    
    51
    +        }
    
    52
    +    }
    
    53
    +
    
    54
    +    companion object {
    
    55
    +        const val ACTION_NIMBUS_TOOLING = "org.mozilla.fenix.NIMBUS_TOOLING"
    
    56
    +    }
    
    57
    +}

  • mobile/android/fenix/app/src/test/java/org/mozilla/fenix/experiments/QANimbusToolingReceiverTest.kt
    1
    +/* This Source Code Form is subject to the terms of the Mozilla Public
    
    2
    + * License, v. 2.0. If a copy of the MPL was not distributed with this
    
    3
    + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
    4
    +
    
    5
    +package org.mozilla.fenix.experiments
    
    6
    +
    
    7
    +import android.content.Context
    
    8
    +import android.content.Intent
    
    9
    +import io.mockk.every
    
    10
    +import kotlinx.coroutines.ExperimentalCoroutinesApi
    
    11
    +import kotlinx.coroutines.Job
    
    12
    +import kotlinx.coroutines.test.UnconfinedTestDispatcher
    
    13
    +import mozilla.components.support.test.robolectric.testContext
    
    14
    +import org.junit.Assert.assertEquals
    
    15
    +import org.junit.Assert.assertFalse
    
    16
    +import org.junit.Assert.assertNull
    
    17
    +import org.junit.Assert.assertTrue
    
    18
    +import org.junit.Before
    
    19
    +import org.junit.Test
    
    20
    +import org.junit.runner.RunWith
    
    21
    +import org.mozilla.fenix.experiments.QANimbusToolingReceiver.Companion.ACTION_NIMBUS_TOOLING
    
    22
    +import org.mozilla.fenix.ext.components
    
    23
    +import org.mozilla.fenix.nimbus.TestNimbusApi
    
    24
    +import org.robolectric.RobolectricTestRunner
    
    25
    +
    
    26
    +@OptIn(ExperimentalCoroutinesApi::class)
    
    27
    +@RunWith(RobolectricTestRunner::class)
    
    28
    +class QANimbusToolingReceiverTest {
    
    29
    +
    
    30
    +    private val nimbusApi = FakeNimbusApi(testContext)
    
    31
    +    private val receiver = QANimbusToolingReceiver(UnconfinedTestDispatcher())
    
    32
    +
    
    33
    +    @Before
    
    34
    +    fun setUp() {
    
    35
    +        every { testContext.components.nimbus.sdk } returns nimbusApi
    
    36
    +    }
    
    37
    +
    
    38
    +    @Test
    
    39
    +    fun `GIVEN a tooling command WHEN the tooling action is received THEN the command is applied`() {
    
    40
    +        receiver.onReceive(testContext, toolingIntent(ACTION_NIMBUS_TOOLING))
    
    41
    +
    
    42
    +        assertEquals(EXPERIMENTS, nimbusApi.appliedExperiments)
    
    43
    +        assertEquals(false, nimbusApi.fetchEnabled)
    
    44
    +        assertTrue(nimbusApi.databaseReset)
    
    45
    +        assertTrue(nimbusApi.stateDumped)
    
    46
    +    }
    
    47
    +
    
    48
    +    @Test
    
    49
    +    fun `GIVEN a tooling command WHEN another action is received THEN the command is ignored`() {
    
    50
    +        receiver.onReceive(testContext, toolingIntent("org.mozilla.fenix.ACTION_PRINT"))
    
    51
    +
    
    52
    +        assertNull(nimbusApi.appliedExperiments)
    
    53
    +        assertNull(nimbusApi.fetchEnabled)
    
    54
    +        assertFalse(nimbusApi.databaseReset)
    
    55
    +        assertFalse(nimbusApi.stateDumped)
    
    56
    +    }
    
    57
    +
    
    58
    +    @Test
    
    59
    +    fun `GIVEN no tooling command WHEN the tooling action is received THEN nothing is applied`() {
    
    60
    +        receiver.onReceive(testContext, Intent(ACTION_NIMBUS_TOOLING))
    
    61
    +
    
    62
    +        assertNull(nimbusApi.appliedExperiments)
    
    63
    +        assertNull(nimbusApi.fetchEnabled)
    
    64
    +        assertFalse(nimbusApi.databaseReset)
    
    65
    +        assertFalse(nimbusApi.stateDumped)
    
    66
    +    }
    
    67
    +
    
    68
    +    @Test
    
    69
    +    fun `GIVEN a tooling command without the version extra WHEN the tooling action is received THEN nothing is applied`() {
    
    70
    +        val intent = toolingIntent(ACTION_NIMBUS_TOOLING).apply { removeExtra("version") }
    
    71
    +
    
    72
    +        receiver.onReceive(testContext, intent)
    
    73
    +
    
    74
    +        assertNull(nimbusApi.appliedExperiments)
    
    75
    +        assertFalse(nimbusApi.stateDumped)
    
    76
    +    }
    
    77
    +
    
    78
    +    private fun toolingIntent(action: String) =
    
    79
    +        Intent(action).apply {
    
    80
    +            putExtra("nimbus-cli", null as String?)
    
    81
    +            putExtra("version", 1)
    
    82
    +            putExtra("experiments", EXPERIMENTS)
    
    83
    +            putExtra("reset-db", true)
    
    84
    +            putExtra("log-state", true)
    
    85
    +        }
    
    86
    +
    
    87
    +    private class FakeNimbusApi(context: Context) : TestNimbusApi(context) {
    
    88
    +        var appliedExperiments: String? = null
    
    89
    +        var fetchEnabled: Boolean? = null
    
    90
    +        var databaseReset = false
    
    91
    +        var stateDumped = false
    
    92
    +
    
    93
    +        override fun applyLocalExperiments(experimentsJson: String): Job {
    
    94
    +            appliedExperiments = experimentsJson
    
    95
    +            return completedJob()
    
    96
    +        }
    
    97
    +
    
    98
    +        override fun resetEnrollmentsDatabase(): Job {
    
    99
    +            databaseReset = true
    
    100
    +            return completedJob()
    
    101
    +        }
    
    102
    +
    
    103
    +        override fun setFetchEnabled(enabled: Boolean) {
    
    104
    +            fetchEnabled = enabled
    
    105
    +        }
    
    106
    +
    
    107
    +        override fun dumpStateToLog() {
    
    108
    +            stateDumped = true
    
    109
    +        }
    
    110
    +
    
    111
    +        private fun completedJob() = Job().apply { complete() }
    
    112
    +    }
    
    113
    +
    
    114
    +    companion object {
    
    115
    +        private const val EXPERIMENTS = """{"data":[]}"""
    
    116
    +    }
    
    117
    +}

  • modules/libpref/init/StaticPrefList.yaml
    ... ... @@ -7834,7 +7834,7 @@
    7834 7834
     #ifdef XP_MACOSX
    
    7835 7835
     - name: gfx.webrender.enable-client-storage
    
    7836 7836
       type: bool
    
    7837
    -  value: true
    
    7837
    +  value: false
    
    7838 7838
       mirror: once
    
    7839 7839
     #endif
    
    7840 7840
     
    

  • netwerk/protocol/http/nsHttpChunkedDecoder.cpp
    ... ... @@ -106,8 +106,15 @@ nsresult nsHttpChunkedDecoder::ParseChunkRemaining(char* buf, uint32_t count,
    106 106
           count = mLineBuf.Length();
    
    107 107
         }
    
    108 108
     
    
    109
    +    // NUL is illegal in a chunk-size or trailer field line (RFC 9110 section
    
    110
    +    // 5.5).
    
    111
    +    if (memchr(buf, '\0', count)) {
    
    112
    +      LOG(("chunked line contains embedded NUL; rejecting\n"));
    
    113
    +      return NS_ERROR_UNEXPECTED;
    
    114
    +    }
    
    115
    +
    
    109 116
         if (mWaitEOF) {
    
    110
    -      if (*buf) {
    
    117
    +      if (count) {
    
    111 118
             LOG(("got trailer: %s\n", buf));
    
    112 119
             // allocate a header array for the trailers on demand
    
    113 120
             if (!mTrailers) {
    
    ... ... @@ -130,7 +137,7 @@ nsresult nsHttpChunkedDecoder::ParseChunkRemaining(char* buf, uint32_t count,
    130 137
             mReachedEOF = true;
    
    131 138
             LOG(("reached end of chunked-body\n"));
    
    132 139
           }
    
    133
    -    } else if (*buf) {
    
    140
    +    } else if (count) {
    
    134 141
           char* endptr;
    
    135 142
           unsigned long parsedval;  // could be 64 bit, could be 32
    
    136 143
     
    

  • testing/web-platform/tests/css/css-writing-modes/crashtests/bidi-inline-continuation-first-in-flow.html
    1
    +<!DOCTYPE html>
    
    2
    +<meta charset="utf-8">
    
    3
    +<link rel="author" title="Ting-Yu Lin" href="">"mailto:tlin@xxxxxxxxxxx">
    
    4
    +<link rel="help" href="">"https://bugzilla.mozilla.org/show_bug.cgi?id=2053578">
    
    5
    +
    
    6
    +<!-- The operations in <script> are generated from one of the runs from
    
    7
    +     the original testcase (Bug 2053578 Comment 5) that triggers
    
    8
    +     the assertion. -->
    
    9
    +
    
    10
    +<body></body>
    
    11
    +
    
    12
    +<script>
    
    13
    +var n1 = document.createElement("div");
    
    14
    +n1.style.width = "50px";
    
    15
    +var n2 = document.createElement("bdo");
    
    16
    +n2.setAttribute("dir", "rtl");
    
    17
    +var n3 = document.createTextNode("كلمة");
    
    18
    +n2.appendChild(n3);
    
    19
    +n1.appendChild(n2);
    
    20
    +var n4 = document.createElement("em");
    
    21
    +var n5 = document.createElement("span");
    
    22
    +var n6 = document.createElement("bdo");
    
    23
    +var n7 = document.createTextNode("word m mix");
    
    24
    +n6.appendChild(n7);
    
    25
    +n5.appendChild(n6);
    
    26
    +var n8 = document.createTextNode("מלל");
    
    27
    +n5.appendChild(n8);
    
    28
    +var n9 = document.createElement("b");
    
    29
    +n9.setAttribute("dir", "ltr");
    
    30
    +n9.style.unicodeBidi = "bidi-override";
    
    31
    +var n10 = document.createTextNode("alpha");
    
    32
    +n9.appendChild(n10);
    
    33
    +var n11 = document.createTextNode("نص مرحبا كلمة");
    
    34
    +n9.appendChild(n11);
    
    35
    +var n12 = document.createTextNode("مرحبا نص نص");
    
    36
    +n9.appendChild(n12);
    
    37
    +n5.appendChild(n9);
    
    38
    +n4.appendChild(n5);
    
    39
    +var n13 = document.createElement("span");
    
    40
    +n13.style.unicodeBidi = "bidi-override";
    
    41
    +var n14 = document.createElement("bdi");
    
    42
    +var n15 = document.createTextNode("اختبار");
    
    43
    +n14.appendChild(n15);
    
    44
    +n13.appendChild(n14);
    
    45
    +var n16 = document.createElement("em");
    
    46
    +var n17 = document.createTextNode("בדיקה מלל m نص");
    
    47
    +n16.appendChild(n17);
    
    48
    +var n18 = document.createTextNode("كلمة");
    
    49
    +n16.appendChild(n18);
    
    50
    +var n19 = document.createTextNode("نص مرحبا كلمة");
    
    51
    +n16.appendChild(n19);
    
    52
    +n13.appendChild(n16);
    
    53
    +var n20 = document.createElement("span");
    
    54
    +var n21 = document.createTextNode("שלום מלל בדיקה שלום");
    
    55
    +n20.appendChild(n21);
    
    56
    +n13.appendChild(n20);
    
    57
    +n4.appendChild(n13);
    
    58
    +n1.appendChild(n4);
    
    59
    +document.body.appendChild(n1);
    
    60
    +var n22 = document.createElement("bdo");
    
    61
    +n22.style.unicodeBidi = "plaintext";
    
    62
    +var n23 = document.createElement("span");
    
    63
    +var n24 = document.createTextNode("עברית שלום مرحبا alpha");
    
    64
    +n23.appendChild(n24);
    
    65
    +n22.appendChild(n23);
    
    66
    +n14.style.direction = "ltr";
    
    67
    +var n25 = document.createTextNode("كلمة שלום");
    
    68
    +n2.insertBefore(n25, n3);
    
    69
    +n21.remove();
    
    70
    +n9.setAttribute("dir", "ltr");
    
    71
    +var n26 = document.createTextNode("בדיקה mm");
    
    72
    +n4.appendChild(n26);
    
    73
    +n12.data = "שלום עברית שלום עברית";
    
    74
    +n7.remove();
    
    75
    +n2.style.direction = "ltr";
    
    76
    +n1.style.width = "102px";
    
    77
    +var n27 = document.createTextNode("עברית mm m");
    
    78
    +n22.appendChild(n27);
    
    79
    +n22.setAttribute("dir", "rtl");
    
    80
    +n4.style.direction = "";
    
    81
    +n14.style.direction = "rtl";
    
    82
    +n22.insertBefore(n9, n23);
    
    83
    +var n28 = document.createElement("br");
    
    84
    +n9.insertBefore(n28, n12);
    
    85
    +n14.style.unicodeBidi = "embed";
    
    86
    +n5.insertBefore(n22, n6);
    
    87
    +n9.style.direction = "";
    
    88
    +n9.style.unicodeBidi = "bidi-override";
    
    89
    +n22.remove();
    
    90
    +var n29 = document.createTextNode("עברית שלום");
    
    91
    +n5.insertBefore(n29, n6);
    
    92
    +n18.data = "mix";
    
    93
    +n19.data = "alpha m word";
    
    94
    +n20.style.direction = "ltr";
    
    95
    +var n30 = document.createTextNode("mm עברית עברית نص");
    
    96
    +n6.appendChild(n30);
    
    97
    +n6.style.unicodeBidi = "isolate";
    
    98
    +n20.style.unicodeBidi = "embed";
    
    99
    +n16.setAttribute("dir", "rtl");
    
    100
    +n2.insertBefore(n20, n25);
    
    101
    +var n31 = document.createTextNode("שלום مرحبا mix mm");
    
    102
    +n2.insertBefore(n31, n20);
    
    103
    +var n32 = document.createTextNode("m בדיקה word mix");
    
    104
    +n20.appendChild(n32);
    
    105
    +n16.removeAttribute("dir");
    
    106
    +n16.setAttribute("dir", "auto");
    
    107
    +n5.remove();
    
    108
    +n17.remove();
    
    109
    +n31.data = "בדיקה mm";
    
    110
    +n14.style.unicodeBidi = "isolate";
    
    111
    +n4.remove();
    
    112
    +n20.style.direction = "";
    
    113
    +n20.style.direction = "rtl";
    
    114
    +n3.data = "בדיקה שלום word";
    
    115
    +n25.data = "mm";
    
    116
    +n25.data = "m mix word";
    
    117
    +n1.style.direction = "rtl";
    
    118
    +n31.data = "كلمة اختبار";
    
    119
    +n20.remove();
    
    120
    +n3.data = "שלום نص";
    
    121
    +n31.remove();
    
    122
    +n2.setAttribute("dir", "ltr");
    
    123
    +n2.removeAttribute("dir");
    
    124
    +n1.insertBefore(n4, n2);
    
    125
    +n19.data = "מלל word";
    
    126
    +n15.remove();
    
    127
    +n13.setAttribute("dir", "ltr");
    
    128
    +n25.remove();
    
    129
    +n2.setAttribute("dir", "ltr");
    
    130
    +n14.appendChild(n2);
    
    131
    +n3.data = "مرحبا اختبار مرحبا";
    
    132
    +n18.data = "שלום";
    
    133
    +n16.insertBefore(n20, n18);
    
    134
    +var n33 = document.createTextNode("كلمة نص mm");
    
    135
    +n2.appendChild(n33);
    
    136
    +n19.data = "اختبار مرحبا كلمة كلمة";
    
    137
    +n18.data = "mm mix mix";
    
    138
    +var n34 = document.createElement("br");
    
    139
    +n4.insertBefore(n34, n13);
    
    140
    +n13.style.unicodeBidi = "isolate-override";
    
    141
    +n13.remove();
    
    142
    +n34.remove();
    
    143
    +n26.data = "كلمة كلمة مرحبا";
    
    144
    +n4.setAttribute("dir", "rtl");
    
    145
    +n26.data = "mm word m mm";
    
    146
    +n26.data = "اختبار نص";
    
    147
    +n4.setAttribute("dir", "auto");
    
    148
    +var n35 = document.createTextNode("مرحبا מלל كلمة שלום");
    
    149
    +n4.insertBefore(n35, n26);
    
    150
    +n4.style.unicodeBidi = "embed";
    
    151
    +n4.style.direction = "";
    
    152
    +var n36 = document.createTextNode("كلمة mix בדיקה نص");
    
    153
    +n4.insertBefore(n36, n35);
    
    154
    +n36.remove();
    
    155
    +n4.removeAttribute("dir");
    
    156
    +n4.style.unicodeBidi = "";
    
    157
    +n1.style.width = "87px";
    
    158
    +n26.data = "שלום מלל מלל עברית";
    
    159
    +var n37 = document.createElement("br");
    
    160
    +n4.insertBefore(n37, n35);
    
    161
    +n35.data = "مرحبا نص اختبار";
    
    162
    +n4.setAttribute("dir", "rtl");
    
    163
    +n33.data = "word alpha mm";
    
    164
    +var n38 = document.createTextNode("שלום word");
    
    165
    +n16.insertBefore(n38, n20);
    
    166
    +n2.setAttribute("dir", "auto");
    
    167
    +n2.remove();
    
    168
    +n37.remove();
    
    169
    +var n39 = document.createTextNode("עברית اختبار בדיקה");
    
    170
    +n13.appendChild(n39);
    
    171
    +var n40 = document.createTextNode("בדיקה m نص نص");
    
    172
    +n13.insertBefore(n40, n14);
    
    173
    +var n41 = document.createElement("br");
    
    174
    +n20.appendChild(n41);
    
    175
    +n35.data = "alpha";
    
    176
    +n16.remove();
    
    177
    +n39.data = "نص mm בדיקה اختبار";
    
    178
    +n40.data = "mix mix word m";
    
    179
    +n35.data = "שלום בדיקה";
    
    180
    +n35.data = "m mix mm m";
    
    181
    +n40.data = "مرحبا اختبار";
    
    182
    +n13.style.unicodeBidi = "embed";
    
    183
    +n4.insertBefore(n16, n26);
    
    184
    +var n42 = document.createTextNode("نص");
    
    185
    +n13.insertBefore(n42, n40);
    
    186
    +n41.remove();
    
    187
    +n20.insertBefore(n2, n32);
    
    188
    +document.body.offsetHeight;
    
    189
    +n39.data = "مرحبا alpha עברית word";
    
    190
    +n18.data = "שלום";
    
    191
    +n2.setAttribute("dir", "auto");
    
    192
    +document.body.offsetHeight;
    
    193
    +n20.style.direction = "ltr";
    
    194
    +</script>

  • third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
    ... ... @@ -443,6 +443,14 @@ void VideoCaptureModulePipeWire::ProcessBuffers() {
    443 443
           continue;
    
    444 444
         }
    
    445 445
     
    
    446
    +    if (static_cast<uint64_t>(spaBuffer->datas[0].chunk->offset) +
    
    447
    +            spaBuffer->datas[0].chunk->size >
    
    448
    +        spaBuffer->datas[0].maxsize) {
    
    449
    +      RTC_LOG(LS_ERROR) << "Dropping frame with invalid size";
    
    450
    +      pw_stream_queue_buffer(stream_, buffer);
    
    451
    +      continue;
    
    452
    +    }
    
    453
    +
    
    446 454
         if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf ||
    
    447 455
             spaBuffer->datas[0].type == SPA_DATA_MemFd) {
    
    448 456
           ScopedBuf frame;
    

  • third_party/libwebrtc/moz-patch-stack/612430e826.no-op-cherry-pick-msg
    1
    +We cherry-picked this in bug 2054625.
    \ No newline at end of file

  • toolkit/components/resistfingerprinting/tests/browser/browser_srcset.js
    ... ... @@ -4,8 +4,20 @@
    4 4
     
    
    5 5
     "use strict";
    
    6 6
     
    
    7
    +async function precacheAssets(tab, zoom) {
    
    8
    +  await SpecialPowers.spawn(tab.linkedBrowser, [zoom], async zoom => {
    
    9
    +    const { Layout } = ChromeUtils.importESModule(
    
    10
    +      "chrome://mochitests/content/browser/accessible/tests/browser/Layout.sys.mjs"
    
    11
    +    );
    
    12
    +    Layout.zoomDocument(content.document, zoom);
    
    13
    +    const { promise, resolve } = Promise.withResolvers();
    
    14
    +    content.requestAnimationFrame(resolve);
    
    15
    +    await promise;
    
    16
    +  });
    
    17
    +}
    
    18
    +
    
    7 19
     async function runForZoomLevel(tab, zoom) {
    
    8
    -  const [dpr, scale] = await SpecialPowers.spawn(
    
    20
    +  const [dpr, scale, cssScale] = await SpecialPowers.spawn(
    
    9 21
         tab.linkedBrowser,
    
    10 22
         [zoom],
    
    11 23
         async zoom => {
    
    ... ... @@ -28,9 +40,16 @@ async function runForZoomLevel(tab, zoom) {
    28 40
           // Workaround: content.devicePixelRatio has the unspoofed value.
    
    29 41
           const dpr = content.wrappedJSObject.devicePixelRatio;
    
    30 42
           const current = img.currentSrc;
    
    31
    -      const scale =
    
    32
    -        current.substring(current.length - 6, current.length - 4) / 10;
    
    33
    -      return [dpr, scale];
    
    43
    +      const scale = parseFloat(current.match(/.*\/([0-9\.]+)\.png$/)[1]);
    
    44
    +
    
    45
    +      const height = content.document
    
    46
    +        .getElementById("imgset")
    
    47
    +        .getBoundingClientRect().height;
    
    48
    +      // The images have been crafted so that it is possible to reverse their
    
    49
    +      // measured size (altered by the zoom) and find the scale.
    
    50
    +      const cssScale = Math.round((height * dpr - 50) / 10) / 10 + 0.3;
    
    51
    +
    
    52
    +      return [dpr, scale, cssScale];
    
    34 53
         }
    
    35 54
       );
    
    36 55
     
    
    ... ... @@ -39,6 +58,11 @@ async function runForZoomLevel(tab, zoom) {
    39 58
         true,
    
    40 59
         `Image scale (${scale}) is within DPR (${dpr})`
    
    41 60
       );
    
    61
    +  is(
    
    62
    +    Math.abs(dpr - cssScale) < 0.1,
    
    63
    +    true,
    
    64
    +    `CSS scale (${cssScale}) is within DPR (${dpr})`
    
    65
    +  );
    
    42 66
     }
    
    43 67
     
    
    44 68
     add_task(async () => {
    
    ... ... @@ -53,6 +77,9 @@ add_task(async () => {
    53 77
         ) + "srcset.html";
    
    54 78
       const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, testPage);
    
    55 79
     
    
    80
    +  for (let zoom = 0.3; zoom < 2.09; zoom += 0.1) {
    
    81
    +    await precacheAssets(tab, zoom);
    
    82
    +  }
    
    56 83
       for (let zoom = 0.3; zoom < 2.09; zoom += 0.1) {
    
    57 84
         await runForZoomLevel(tab, zoom);
    
    58 85
       }
    

  • toolkit/components/resistfingerprinting/tests/browser/srcset.html
    1 1
     <!DOCTYPE html>
    
    2 2
     <html>
    
    3
    +  <head>
    
    4
    +    <style>
    
    5
    +#imgset {
    
    6
    +  content: image-set(
    
    7
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50"></svg>') 0.3x,
    
    8
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"></svg>') 0.4x,
    
    9
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="70" height="70"></svg>') 0.5x,
    
    10
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80"></svg>') 0.6x,
    
    11
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="90" height="90"></svg>') 0.7x,
    
    12
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"></svg>') 0.8x,
    
    13
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="110" height="110"></svg>') 0.9x,
    
    14
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="120" height="120"></svg>') 1.0x,
    
    15
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="130" height="130"></svg>') 1.1x,
    
    16
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140"></svg>') 1.2x,
    
    17
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150"></svg>') 1.3x,
    
    18
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160"></svg>') 1.4x,
    
    19
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="170" height="170"></svg>') 1.5x,
    
    20
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="180" height="180"></svg>') 1.6x,
    
    21
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="190" height="190"></svg>') 1.7x,
    
    22
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"></svg>') 1.8x,
    
    23
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="210" height="210"></svg>') 1.9x,
    
    24
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="220" height="220"></svg>') 2.0x,
    
    25
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="230" height="230"></svg>') 2.1x,
    
    26
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="240" height="240"></svg>') 2.2x,
    
    27
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250"></svg>') 2.3x,
    
    28
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="260" height="260"></svg>') 2.4x,
    
    29
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="270" height="270"></svg>') 2.5x,
    
    30
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="280" height="280"></svg>') 2.6x,
    
    31
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="290" height="290"></svg>') 2.7x,
    
    32
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300"></svg>') 2.8x,
    
    33
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="310" height="310"></svg>') 2.9x,
    
    34
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="320" height="320"></svg>') 3.0x,
    
    35
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="330" height="330"></svg>') 3.1x,
    
    36
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="340" height="340"></svg>') 3.2x,
    
    37
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="350" height="350"></svg>') 3.3x,
    
    38
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="360" height="360"></svg>') 3.4x,
    
    39
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="370" height="370"></svg>') 3.5x,
    
    40
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="380" height="380"></svg>') 3.6x,
    
    41
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="390" height="390"></svg>') 3.7x,
    
    42
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400"></svg>') 3.8x,
    
    43
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="410" height="410"></svg>') 3.9x,
    
    44
    +      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="420" height="420"></svg>') 4.0x
    
    45
    +    );
    
    46
    +}
    
    47
    +    </style>
    
    48
    +  </head>
    
    3 49
       <body>
    
    4 50
         <img id="srcset" srcset="
    
    5
    -        03.png 0.3x, 04.png 0.4x, 05.png 0.5x, 06.png 0.6x, 07.png 0.7x, 08.png 0.8x, 09.png 0.9x,
    
    6
    -        10.png 1x, 11.png 1.1x, 12.png 1.2x, 13.png 1.3x, 14.png 1.4x, 15.png 1.5x, 16.png 1.6x, 17.png 1.7x, 18.png 1.8x, 19.png 1.9x,
    
    7
    -        20.png 2x, 21.png 2.1x, 22.png 2.2x, 23.png 2.3x, 24.png 2.4x, 25.png 2.5x, 26.png 2.6x, 27.png 2.7x, 28.png 2.8x, 29.png 2.9x,
    
    8
    -        30.png 3x, 31.png 3.1x, 32.png 3.2x, 33.png 3.3x, 34.png 3.4x, 35.png 3.5x, 36.png 3.6x, 37.png 3.7x, 38.png 3.8x, 39.png 3.9x,
    
    9
    -        40.png 4x
    
    51
    +        0.65.png 0.65x, 0.85.png 0.85x, 1.05.png 1.05x, 1.25.png 1.25x, 1.45.png 1.45x, 1.65.png 1.65x, 1.85.png 1.85x,
    
    52
    +        2.05.png 2.05x, 2.25.png 2.25x, 2.45.png 2.45x, 2.65.png 2.65x, 2.9.png 2.9x, 3.0.png 3.0x, 3.2.png 3.2x,
    
    53
    +        3.4.png 3.4x, 3.6.png 3.6x, 3.8.png 3.8x, 4.0.png 4.0x
    
    10 54
           ">
    
    55
    +    <div id="imgset"></div>
    
    11 56
       </body>
    
    12 57
     </html>

  • widget/gtk/nsDragService.cpp
    ... ... @@ -1741,6 +1741,14 @@ void nsDragSession::SourceEndDragSession(GdkDragContext* aContext,
    1741 1741
       LOGDRAGSERVICE("SourceEndDragSession(%p) result %s\n", aContext,
    
    1742 1742
                      kGtkDragResults[aResult]);
    
    1743 1743
     
    
    1744
    +  // GTK drops its last reference right after drag-end, so reset ours now.
    
    1745
    +  //
    
    1746
    +  // Clearing only from EndDragSessionImpl is not enough (bug 2058661): that
    
    1747
    +  // runs from an async runnable, by which point the pointer already dangles.
    
    1748
    +  if (mSourceWindow) {
    
    1749
    +    mSourceWindow->SetDragSource(nullptr);
    
    1750
    +  }
    
    1751
    +
    
    1744 1752
       // this just releases the list of data items that we provide
    
    1745 1753
       mSourceDataItems = nullptr;
    
    1746 1754
     
    

  • widget/windows/SystemStatusBar.cpp
    ... ... @@ -91,10 +91,10 @@ StatusBarEntry::StatusBarEntry(Element* aMenu) : mMenu(aMenu), mInitted(false) {
    91 91
     }
    
    92 92
     
    
    93 93
     StatusBarEntry::~StatusBarEntry() {
    
    94
    +  Destroy();
    
    94 95
       if (!mInitted) {
    
    95 96
         return;
    
    96 97
       }
    
    97
    -  Destroy();
    
    98 98
       ::Shell_NotifyIconW(NIM_DELETE, &mIconData);
    
    99 99
       VERIFY(::DestroyWindow(mIconData.hWnd));
    
    100 100
     }
    

  • widget/windows/filedialog/WinFileDialogCommands.cpp
    ... ... @@ -233,18 +233,24 @@ mozilla::Result<nsString, Error> GetFolderResults(::IFileDialog* dialog) {
    233 233
       }
    
    234 234
     
    
    235 235
       // If the user chose a Win7 Library, resolve to the library's
    
    236
    -  // default save folder.
    
    237
    -  RefPtr<IShellLibrary> shellLib;
    
    238
    -  RefPtr<IShellItem> folderPath;
    
    239
    -  MOZ_ENSURE_HRESULT_OK(
    
    240
    -      "CoCreateInstance(CLSID_ShellLibrary)",
    
    241
    -      CoCreateInstance(CLSID_ShellLibrary, nullptr, CLSCTX_INPROC_SERVER,
    
    242
    -                       IID_IShellLibrary, getter_AddRefs(shellLib)));
    
    243
    -
    
    244
    -  if (shellLib && SUCCEEDED(shellLib->LoadLibraryFromItem(item, STGM_READ)) &&
    
    245
    -      SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
    
    246
    -                                               getter_AddRefs(folderPath)))) {
    
    247
    -    item.swap(folderPath);
    
    236
    +  // default save folder. Only do this for items which are known not to be
    
    237
    +  // filesystem objects, like the user's Documents library (but not .library-ms
    
    238
    +  // files).
    
    239
    +  SFGAOF attrs = 0;
    
    240
    +  if (SUCCEEDED(item->GetAttributes(SFGAO_FILESYSTEM, &attrs)) &&
    
    241
    +      !(attrs & SFGAO_FILESYSTEM)) {
    
    242
    +    RefPtr<IShellLibrary> shellLib;
    
    243
    +    RefPtr<IShellItem> folderPath;
    
    244
    +    MOZ_ENSURE_HRESULT_OK(
    
    245
    +        "CoCreateInstance(CLSID_ShellLibrary)",
    
    246
    +        CoCreateInstance(CLSID_ShellLibrary, nullptr, CLSCTX_INPROC_SERVER,
    
    247
    +                         IID_IShellLibrary, getter_AddRefs(shellLib)));
    
    248
    +
    
    249
    +    if (shellLib && SUCCEEDED(shellLib->LoadLibraryFromItem(item, STGM_READ)) &&
    
    250
    +        SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
    
    251
    +                                                 getter_AddRefs(folderPath)))) {
    
    252
    +      item.swap(folderPath);
    
    253
    +    }
    
    248 254
       }
    
    249 255
     
    
    250 256
       // get the folder's file system path
    

  • _______________________________________________
    tor-commits mailing list -- tor-commits@xxxxxxxxxxxxxxxxxxxx
    To unsubscribe send an email to tor-commits-leave@xxxxxxxxxxxxxxxxxxxx