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

[tor-commits] [Git][tpo/applications/mullvad-browser][mullvad-browser-140.14.0esr-15.0-1] 12 commits: Bug 1978587 - Forward onEnterAnimationComplete to interested fragments r=android-reviewers,twhite



Title: GitLab

ma1 pushed to branch mullvad-browser-140.14.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser

Commits:

  • 9d3a9bf3
    by Marcin Koziński at 2026-08-17T17:52:12+02:00
    Bug 1978587 - Forward onEnterAnimationComplete to interested fragments r=android-reviewers,twhite
    
    Differential Revision: https://phabricator.services.mozilla.com/D306954
    
  • 14ab8ec4
    by Harveer Singh at 2026-08-17T17:52:12+02:00
    Bug 2025732: Increase Cache API opaque response padding.  a=RyanVM DONTBUILD
    
    Original Revision: https://phabricator.services.mozilla.com/D313509
    
    Differential Revision: https://phabricator.services.mozilla.com/D315608
    
  • 18daf32e
    by Rob Wu at 2026-08-17T17:52:13+02:00
    Bug 2045676 - Gracefully handle broken files in verifyBundleSignedState  a=RyanVM DONTBUILD
    
    Original Revision: https://phabricator.services.mozilla.com/D305180
    
    Differential Revision: https://phabricator.services.mozilla.com/D315593
    
  • 51071b8f
    by Lee Salzman at 2026-08-17T17:52:13+02:00
    Bug 2045711.  a=diannaS
    
    Original Revision: https://phabricator.services.mozilla.com/D311733
    
    Differential Revision: https://phabricator.services.mozilla.com/D312888
    
  • bea32e17
    by Jim Blandy at 2026-08-17T17:52:14+02:00
    Bug 2045796: Saturate when rounding up pixman trapezoid edges.  a=diannaS DONTBUILD
    
    When rounding the edge coordinates of a non-antialised edge upwards,
    use saturating addition, just in case the coordinates are close to the
    limit of `pixman_fixed_t`'s range.
    
    Original Revision: https://phabricator.services.mozilla.com/D314811
    
    Differential Revision: https://phabricator.services.mozilla.com/D317287
    
  • 4c1edd7e
    by Karl Tomlinson at 2026-08-17T17:52:14+02:00
    Bug 2050380 Make shared memory transfer conditional on IsSharedMemoryAllowed()  a=diannaS DONTBUILD
    
    Original Revision: https://phabricator.services.mozilla.com/D312653
    
    Differential Revision: https://phabricator.services.mozilla.com/D313366
    
  • 67ac4951
    by Andrea Marchesini at 2026-08-17T17:52:15+02:00
    Bug 2048353 - Improve worker shutdown support in CookieStoreNotificationWatcher   a=diannaS DONTBUILD
    
    Original Revision: https://phabricator.services.mozilla.com/D311765
    
    Differential Revision: https://phabricator.services.mozilla.com/D314995
    
  • f83930c8
    by Henri Sivonen at 2026-08-17T17:52:15+02:00
    Bug 2053153 - Only check for high surrogates when intending to avoid split pair.  a=diannaS DONTBUILD
    
    Original Revision: https://phabricator.services.mozilla.com/D314632
    
    Differential Revision: https://phabricator.services.mozilla.com/D316466
    
  • 6b68c8bc
    by Olli Pettay at 2026-08-17T17:52:16+02:00
    Bug 2054643, make button's EndSubmitClick handling consistent with input type=button,  a=diannaS DONTBUILD
    
    Original Revision: https://phabricator.services.mozilla.com/D315429
    
    Differential Revision: https://phabricator.services.mozilla.com/D315956
    
  • 8014b877
    by Dimi at 2026-08-17T17:52:16+02:00
    Bug 2054687 - Check iframe's parent matches the browsing context,  a=diannaS DONTBUILD
    
    Original Revision: https://phabricator.services.mozilla.com/D312950
    
    Differential Revision: https://phabricator.services.mozilla.com/D313656
    
  • f4c87ed0
    by Lee Salzman at 2026-08-17T17:52:17+02:00
    Bug 2060000. r=gfx-reviewers,nical, a=dsmith
    
    Differential Revision: https://phabricator.services.mozilla.com/D315942
    
  • a3205d37
    by Emilio Cobos Álvarez at 2026-08-17T17:52:17+02:00
    Bug 2060048 - Force revalidation of Vary: cookie subresources.  a=diannaS
    
    I think this would fix the image, css, and script caches.
    
    Original Revision: https://phabricator.services.mozilla.com/D315988
    
    Differential Revision: https://phabricator.services.mozilla.com/D317319
    

22 changed files:

Changes:

  • dom/base/nsContentUtils.cpp
    ... ... @@ -12177,6 +12177,23 @@ nsContentUtils::GetSubresourceCacheValidationInfo(nsIRequest* aRequest,
    12177 12177
         if (!info.mMustRevalidate) {
    
    12178 12178
           Unused << httpChannel->IsNoCacheResponse(&info.mMustRevalidate);
    
    12179 12179
         }
    
    12180
    +
    
    12181
    +    if (!info.mMustRevalidate) {
    
    12182
    +      nsAutoCString vary;
    
    12183
    +      (void)httpChannel->GetResponseHeader("vary"_ns, vary);
    
    12184
    +      info.mMustRevalidate = [&] {
    
    12185
    +        for (const nsACString& token :
    
    12186
    +             nsCCharSeparatedTokenizer(vary, ',').ToRange()) {
    
    12187
    +          if (token.EqualsLiteral("*")) {
    
    12188
    +            return true;
    
    12189
    +          }
    
    12190
    +          if (token.EqualsIgnoreCase("cookie")) {
    
    12191
    +            return true;
    
    12192
    +          }
    
    12193
    +        }
    
    12194
    +        return false;
    
    12195
    +      }();
    
    12196
    +    }
    
    12180 12197
       }
    
    12181 12198
     
    
    12182 12199
       // data: URIs are safe to cache across documents under any circumstance, so we
    

  • dom/cache/FileUtils.cpp
    ... ... @@ -47,7 +47,7 @@ namespace {
    47 47
     
    
    48 48
     // Const variable for generate padding size.
    
    49 49
     // XXX This will be tweaked to something more meaningful in Bug 1383656.
    
    50
    -const int64_t kRoundUpNumber = 20480;
    
    50
    +const int64_t kRoundUpNumber = 131072;
    
    51 51
     
    
    52 52
     // At the moment, the encrypted stream block size is assumed to be unchangeable
    
    53 53
     // between encrypting and decrypting blobs. This assumptions holds as long as we
    

  • dom/canvas/WebGLContextGL.cpp
    ... ... @@ -1361,8 +1361,8 @@ void WebGLContext::UniformData(
    1361 1361
       // -
    
    1362 1362
     
    
    1363 1363
       const auto lengthInType = data.size();
    
    1364
    -  const auto elemCount = lengthInType / channels;
    
    1365
    -  if (elemCount > 1 && !validationInfo.isArray) {
    
    1364
    +  const size_t availElemCount = lengthInType / channels;
    
    1365
    +  if (availElemCount > 1 && !validationInfo.isArray) {
    
    1366 1366
         GenerateError(
    
    1367 1367
             LOCAL_GL_INVALID_OPERATION,
    
    1368 1368
             "(uniform %s) `values` length (%u) must exactly match size of %s.",
    
    ... ... @@ -1370,6 +1370,10 @@ void WebGLContext::UniformData(
    1370 1370
             EnumString(activeInfo.elemType).c_str());
    
    1371 1371
         return;
    
    1372 1372
       }
    
    1373
    +  const size_t elemCount =
    
    1374
    +      validationInfo.isArray
    
    1375
    +          ? std::min(availElemCount, size_t(activeInfo.elemCount))
    
    1376
    +          : availElemCount;
    
    1373 1377
     
    
    1374 1378
       // -
    
    1375 1379
     
    

  • dom/cookiestore/CookieStoreNotificationWatcherWrapper.cpp
    ... ... @@ -99,13 +99,13 @@ void CookieStoreNotificationWatcherWrapper::ResolvePromiseWhenNotified(
    99 99
               mEventTarget(GetCurrentSerialEventTarget()) {}
    
    100 100
     
    
    101 101
         NS_IMETHOD Run() override {
    
    102
    -      mPromise->MaybeResolveWithUndefined();
    
    103
    -      mPromise = nullptr;
    
    102
    +      if (mPromise) {
    
    103
    +        mPromise->MaybeResolveWithUndefined();
    
    104
    +        mPromise = nullptr;
    
    105
    +      }
    
    104 106
           return NS_OK;
    
    105 107
         }
    
    106 108
     
    
    107
    -    bool HasPromise() const { return !!mPromise; }
    
    108
    -
    
    109 109
        private:
    
    110 110
         ~PromiseResolver() {
    
    111 111
           NS_ProxyRelease(
    
    ... ... @@ -140,10 +140,8 @@ void CookieStoreNotificationWatcherWrapper::ResolvePromiseWhenNotified(
    140 140
       auto callback = [resolver = RefPtr(resolver),
    
    141 141
                        eventTarget = RefPtr(GetCurrentSerialEventTarget()),
    
    142 142
                        workerRef = RefPtr(workerRef)] {
    
    143
    -    if (resolver->HasPromise()) {
    
    144
    -      RefPtr<Runnable> runnable(resolver);
    
    145
    -      eventTarget->Dispatch(runnable.forget());
    
    146
    -    }
    
    143
    +    RefPtr<Runnable> runnable(resolver);
    
    144
    +    eventTarget->Dispatch(runnable.forget());
    
    147 145
       };
    
    148 146
     
    
    149 147
       if (!NS_IsMainThread()) {
    

  • dom/fetch/InternalResponse.cpp
    ... ... @@ -25,7 +25,7 @@ namespace {
    25 25
     
    
    26 26
     // Const variable for generate padding size
    
    27 27
     // XXX This will be tweaked to something more meaningful in Bug 1383656.
    
    28
    -const uint32_t kMaxRandomNumber = 102400;
    
    28
    +const uint32_t kMaxRandomNumber = 1048576;
    
    29 29
     
    
    30 30
     }  // namespace
    
    31 31
     
    

  • dom/html/HTMLButtonElement.cpp
    ... ... @@ -256,8 +256,8 @@ void EndSubmitClick(EventChainVisitor& aVisitor) {
    256 256
     }
    
    257 257
     
    
    258 258
     void HTMLButtonElement::ActivationBehavior(EventChainPostVisitor& aVisitor) {
    
    259
    +  auto endSubmit = MakeScopeExit([&] { EndSubmitClick(aVisitor); });
    
    259 260
       if (!aVisitor.mPresContext) {
    
    260
    -    // Should check whether EndSubmitClick is needed here.
    
    261 261
         return;
    
    262 262
       }
    
    263 263
     
    

  • dom/html/HTMLFormElement.cpp
    ... ... @@ -817,6 +817,10 @@ nsresult HTMLFormElement::SubmitSubmission(
    817 817
         return NS_OK;
    
    818 818
       }
    
    819 819
     
    
    820
    +  if (doc->GetSandboxFlags() & SANDBOXED_FORMS) {
    
    821
    +    return NS_OK;
    
    822
    +  }
    
    823
    +
    
    820 824
       // _javascript_ URIs are not really submissions; they just call a function.
    
    821 825
       // Also, they may synchronously call submit(), and we want them to be able to
    
    822 826
       // do so while still disallowing other double submissions. (Bug 139798)
    

  • dom/media/webaudio/AudioWorkletNode.cpp
    ... ... @@ -767,7 +767,10 @@ already_AddRefed<AudioWorkletNode> AudioWorkletNode::Constructor(
    767 767
       // can share memory.
    
    768 768
       JS::CloneDataPolicy cloneDataPolicy;
    
    769 769
       cloneDataPolicy.allowIntraClusterClonableSharedObjects();
    
    770
    -  cloneDataPolicy.allowSharedMemoryObjects();
    
    770
    +  nsIGlobalObject* currentGlobal = xpc::CurrentNativeGlobal(cx);
    
    771
    +  if (currentGlobal->IsSharedMemoryAllowed()) {
    
    772
    +    cloneDataPolicy.allowSharedMemoryObjects();
    
    773
    +  }
    
    771 774
     
    
    772 775
       // StructuredCloneHolder does not have a move constructor.  Instead allocate
    
    773 776
       // memory so that the pointer can be passed to the rendering thread.
    

  • gfx/cairo/README
    ... ... @@ -63,3 +63,5 @@ pixman-export.patch: make sure pixman symbols are not exported in libxul
    63 63
     pixman-interp.patch: use lower quality interpolation by default on mobile
    
    64 64
     
    
    65 65
     pixman-rename.patch: include pixman-rename.h for renaming of external symbols
    
    66
    +
    
    67
    +pixman-edge-saturate.patch: Saturate when rounding up trapezoid edges

  • gfx/cairo/cairo/src/cairo-truetype-subset.c
    ... ... @@ -1451,13 +1451,22 @@ find_name (tt_name_t *name, unsigned long size, int name_id, int platform, int e
    1451 1451
     {
    
    1452 1452
         tt_name_record_t *record;
    
    1453 1453
         unsigned int i, len;
    
    1454
    +    unsigned long max_records;
    
    1454 1455
         char *str;
    
    1455 1456
         char *p;
    
    1456 1457
         cairo_bool_t has_tag;
    
    1457 1458
         cairo_status_t status;
    
    1458 1459
     
    
    1459 1460
         str = NULL;
    
    1460
    -    for (i = 0; i < MIN(be16_to_cpu (name->num_records), size / sizeof(name->records[0])); i++) {
    
    1461
    +    /* records[] starts after the 6-byte tt_name_t header (format,
    
    1462
    +     * num_records, strings_offset); only records lying entirely within the
    
    1463
    +     * size-byte table may be read. */
    
    1464
    +    if (size < offsetof (tt_name_t, records)) {
    
    1465
    +	*str_out = NULL;
    
    1466
    +	return CAIRO_STATUS_SUCCESS;
    
    1467
    +    }
    
    1468
    +    max_records = (size - offsetof (tt_name_t, records)) / sizeof(name->records[0]);
    
    1469
    +    for (i = 0; i < MIN(be16_to_cpu (name->num_records), max_records); i++) {
    
    1461 1470
             record = &(name->records[i]);
    
    1462 1471
     	if (be16_to_cpu (record->name) == name_id &&
    
    1463 1472
     	    be16_to_cpu (record->platform) == platform &&
    

  • gfx/cairo/libpixman/src/pixman-edge-imp.h
    ... ... @@ -53,10 +53,13 @@ RASTERIZE_EDGES (pixman_image_t *image,
    53 53
     	 * when the sample point lies exactly on the line, we round towards
    
    54 54
     	 * north-west.
    
    55 55
     	 *
    
    56
    +	 * Use 64 bits to get a saturating add, in case lx or rx are near
    
    57
    +	 * the limits of pixman_fixed_t.
    
    58
    +	 *
    
    56 59
     	 * (The AA case does a similar  adjustment in RENDER_SAMPLES_X)
    
    57 60
     	 */
    
    58
    -	lx += X_FRAC_FIRST(1) - pixman_fixed_e;
    
    59
    -	rx += X_FRAC_FIRST(1) - pixman_fixed_e;
    
    61
    +	lx = (pixman_fixed_t) MIN ((int64_t) lx + (X_FRAC_FIRST(1) - pixman_fixed_e), INT32_MAX);
    
    62
    +	rx = (pixman_fixed_t) MIN ((int64_t) rx + (X_FRAC_FIRST(1) - pixman_fixed_e), INT32_MAX);
    
    60 63
     #endif
    
    61 64
     	/* clip X */
    
    62 65
     	if (lx < 0)
    

  • gfx/cairo/patches/0043-Bug-2045711-records-size-check.patch
    1
    +diff --git a/gfx/cairo/cairo/src/cairo-truetype-subset.c b/gfx/cairo/cairo/src/cairo-truetype-subset.c
    
    2
    +--- a/gfx/cairo/cairo/src/cairo-truetype-subset.c
    
    3
    ++++ b/gfx/cairo/cairo/src/cairo-truetype-subset.c
    
    4
    +@@ -1446,23 +1446,32 @@ cleanup:
    
    5
    +  */
    
    6
    + #define MAX_FONT_NAME_LENGTH 127
    
    7
    + 
    
    8
    + static cairo_status_t
    
    9
    + find_name (tt_name_t *name, unsigned long size, int name_id, int platform, int encoding, int language, char **str_out)
    
    10
    + {
    
    11
    +     tt_name_record_t *record;
    
    12
    +     unsigned int i, len;
    
    13
    ++    unsigned long max_records;
    
    14
    +     char *str;
    
    15
    +     char *p;
    
    16
    +     cairo_bool_t has_tag;
    
    17
    +     cairo_status_t status;
    
    18
    + 
    
    19
    +     str = NULL;
    
    20
    +-    for (i = 0; i < MIN(be16_to_cpu (name->num_records), size / sizeof(name->records[0])); i++) {
    
    21
    ++    /* records[] starts after the 6-byte tt_name_t header (format,
    
    22
    ++     * num_records, strings_offset); only records lying entirely within the
    
    23
    ++     * size-byte table may be read. */
    
    24
    ++    if (size < offsetof (tt_name_t, records)) {
    
    25
    ++	*str_out = NULL;
    
    26
    ++	return CAIRO_STATUS_SUCCESS;
    
    27
    ++    }
    
    28
    ++    max_records = (size - offsetof (tt_name_t, records)) / sizeof(name->records[0]);
    
    29
    ++    for (i = 0; i < MIN(be16_to_cpu (name->num_records), max_records); i++) {
    
    30
    +         record = &(name->records[i]);
    
    31
    + 	if (be16_to_cpu (record->name) == name_id &&
    
    32
    + 	    be16_to_cpu (record->platform) == platform &&
    
    33
    +             be16_to_cpu (record->encoding) == encoding &&
    
    34
    + 	    (language == -1 || be16_to_cpu (record->language) == language)) {
    
    35
    + 
    
    36
    + 	    len = be16_to_cpu (record->length);
    
    37
    + 	    if (platform == 3 && len > MAX_FONT_NAME_LENGTH*2) /* UTF-16 name */

  • gfx/cairo/pixman-edge-saturate.patch
    1
    +From: Jim Blandy <jimb@xxxxxxxxxxx>
    
    2
    +Subject: Saturate when rounding up trapezoid edges
    
    3
    +
    
    4
    +diff --git a/gfx/cairo/libpixman/src/pixman-edge-imp.h b/gfx/cairo/libpixman/src/pixman-edge-imp.h
    
    5
    +index a4698eddb281..39e8d71d2568 100644
    
    6
    +--- a/gfx/cairo/libpixman/src/pixman-edge-imp.h
    
    7
    ++++ b/gfx/cairo/libpixman/src/pixman-edge-imp.h
    
    8
    +@@ -53,10 +53,13 @@ RASTERIZE_EDGES (pixman_image_t  *image,
    
    9
    + 	 * when the sample point lies exactly on the line, we round towards
    
    10
    + 	 * north-west.
    
    11
    + 	 *
    
    12
    ++	 * Use 64 bits to get a saturating add, in case lx or rx are near
    
    13
    ++	 * the limits of pixman_fixed_t.
    
    14
    ++	 *
    
    15
    + 	 * (The AA case does a similar  adjustment in RENDER_SAMPLES_X)
    
    16
    + 	 */
    
    17
    +-	lx += X_FRAC_FIRST(1) - pixman_fixed_e;
    
    18
    +-	rx += X_FRAC_FIRST(1) - pixman_fixed_e;
    
    19
    ++	lx = (pixman_fixed_t) MIN ((int64_t) lx + (X_FRAC_FIRST(1) - pixman_fixed_e), INT32_MAX);
    
    20
    ++	rx = (pixman_fixed_t) MIN ((int64_t) rx + (X_FRAC_FIRST(1) - pixman_fixed_e), INT32_MAX);
    
    21
    + #endif
    
    22
    + 	/* clip X */
    
    23
    + 	if (lx < 0)

  • mobile/android/android-components/components/feature/sitepermissions/src/main/java/mozilla/components/feature/sitepermissions/SitePermissionsDialogFragment.kt
    ... ... @@ -25,6 +25,7 @@ import androidx.core.graphics.drawable.toDrawable
    25 25
     import mozilla.components.support.base.android.NoObscuredTouchesDialogFragment
    
    26 26
     import mozilla.components.support.base.log.logger.Logger
    
    27 27
     import mozilla.components.support.ktx.util.PromptAbuserDetector
    
    28
    +import mozilla.components.support.utils.OnEnterAnimationCompleteListener
    
    28 29
     
    
    29 30
     internal const val KEY_SESSION_ID = "KEY_SESSION_ID"
    
    30 31
     internal const val KEY_TITLE = "KEY_TITLE"
    
    ... ... @@ -42,7 +43,9 @@ private const val KEY_IS_NOTIFICATION_REQUEST = "KEY_IS_NOTIFICATION_REQUEST"
    42 43
     private const val DEFAULT_VALUE = Int.MAX_VALUE
    
    43 44
     private const val KEY_PERMISSION_ID = "KEY_PERMISSION_ID"
    
    44 45
     
    
    45
    -internal open class SitePermissionsDialogFragment : NoObscuredTouchesDialogFragment() {
    
    46
    +internal open class SitePermissionsDialogFragment :
    
    47
    +    NoObscuredTouchesDialogFragment(),
    
    48
    +    OnEnterAnimationCompleteListener {
    
    46 49
     
    
    47 50
         private val logger = Logger("SitePermissionsDialogFragment")
    
    48 51
     
    
    ... ... @@ -124,6 +127,11 @@ internal open class SitePermissionsDialogFragment : NoObscuredTouchesDialogFragm
    124 127
             feature?.onDismiss(permissionRequestId, sessionId)
    
    125 128
         }
    
    126 129
     
    
    130
    +    override fun onEnterAnimationComplete() {
    
    131
    +        // Extend the positive button click delay.
    
    132
    +        promptAbuserDetector.updateJSDialogAbusedState()
    
    133
    +    }
    
    134
    +
    
    127 135
         private fun Dialog.setContainerView(rootView: View) {
    
    128 136
             if (dialogShouldWidthMatchParent) {
    
    129 137
                 setContentView(rootView)
    

  • mobile/android/android-components/components/support/utils/src/main/java/mozilla/components/support/utils/OnEnterAnimationCompleteListener.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 mozilla.components.support.utils
    
    6
    +
    
    7
    +/**
    
    8
    + * Allows forwarding [android.app.Activity.onEnterAnimationComplete] to other classes
    
    9
    + * (e.g. fragments) that want to participate in handling it.
    
    10
    + */
    
    11
    +interface OnEnterAnimationCompleteListener {
    
    12
    +    /**
    
    13
    +     * Called when the Activity's entering animation has completed.
    
    14
    +     */
    
    15
    +    fun onEnterAnimationComplete()
    
    16
    +}

  • mobile/android/fenix/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserActivity.kt
    ... ... @@ -13,6 +13,7 @@ import androidx.annotation.VisibleForTesting
    13 13
     import androidx.core.net.toUri
    
    14 14
     import mozilla.components.browser.state.selector.findCustomTab
    
    15 15
     import mozilla.components.browser.state.state.SessionState
    
    16
    +import mozilla.components.support.utils.OnEnterAnimationCompleteListener
    
    16 17
     import mozilla.components.support.utils.SafeIntent
    
    17 18
     import org.mozilla.fenix.HomeActivity
    
    18 19
     import org.mozilla.fenix.ext.components
    
    ... ... @@ -95,5 +96,14 @@ open class ExternalAppBrowserActivity : HomeActivity() {
    95 96
         override fun onEnterAnimationComplete() {
    
    96 97
             super.onEnterAnimationComplete()
    
    97 98
             isFinishedAnimating = true
    
    99
    +
    
    100
    +        val fragments = supportFragmentManager.fragments.toMutableList()
    
    101
    +        while (fragments.isNotEmpty()) {
    
    102
    +            val fragment = fragments.removeAt(0)
    
    103
    +            if (fragment is OnEnterAnimationCompleteListener) {
    
    104
    +                fragment.onEnterAnimationComplete()
    
    105
    +            }
    
    106
    +            fragments.addAll(fragment.childFragmentManager.fragments)
    
    107
    +        }
    
    98 108
         }
    
    99 109
     }

  • parser/expat/13_high_surrogate_mask.patch
    1
    +diff --git a/expat/expat/lib/xmltok.c b/expat/expat/lib/xmltok.c
    
    2
    +--- a/expat/expat/lib/xmltok.c
    
    3
    ++++ b/expat/expat/lib/xmltok.c
    
    4
    +@@ -707,7 +707,9 @@ unicode_byte_type(char hi, char lo) {
    
    5
    +     fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */  \
    
    6
    +     /* Avoid copying first half only of surrogate */                           \
    
    7
    +     if (fromLim - *fromP > ((toLim - *toP) << 1)                               \
    
    8
    +-        && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) {                             \
    
    9
    ++/* BEGIN MOZILLA CHANGE (Only high surrogate mask) */                          \
    
    10
    ++        && (GET_HI(fromLim - 2) & 0xFC) == 0xD8) {                             \
    
    11
    ++/* END MOZILLA CHANGE */                                                       \
    
    12
    +       fromLim -= 2;                                                            \
    
    13
    +       res = XML_CONVERT_INPUT_INCOMPLETE;                                      \
    
    14
    +     }                                                                          \

  • parser/expat/expat/lib/xmltok.c
    ... ... @@ -705,7 +705,9 @@ unicode_byte_type(char hi, char lo) {
    705 705
         fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */  \
    
    706 706
         /* Avoid copying first half only of surrogate */                           \
    
    707 707
         if (fromLim - *fromP > ((toLim - *toP) << 1)                               \
    
    708
    -        && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) {                             \
    
    708
    +/* BEGIN MOZILLA CHANGE (Only high surrogate mask) */                          \
    
    709
    +        && (GET_HI(fromLim - 2) & 0xFC) == 0xD8) {                             \
    
    710
    +/* END MOZILLA CHANGE */                                                       \
    
    709 711
           fromLim -= 2;                                                            \
    
    710 712
           res = XML_CONVERT_INPUT_INCOMPLETE;                                      \
    
    711 713
         }                                                                          \
    

  • parser/expat/moz.yaml
    ... ... @@ -62,3 +62,4 @@ vendoring:
    62 62
         - 10_version_limit.patch
    
    63 63
         - 11_no_debug_report.patch
    
    64 64
         - 12_unused.patch
    
    65
    +    - 13_high_surrogate_mask.patch

  • toolkit/components/formautofill/FormAutofillParent.sys.mjs
    ... ... @@ -474,6 +474,10 @@ export class FormAutofillParent extends JSWindowActorParent {
    474 474
           }
    
    475 475
     
    
    476 476
           const iframeBC = BrowsingContext.get(field.browsingContextId);
    
    477
    +      if (!iframeBC || iframeBC.parent != browsingContext) {
    
    478
    +        continue;
    
    479
    +      }
    
    480
    +
    
    477 481
           const [fields] = await this.identifyAllSubTreeFields(
    
    478 482
             iframeBC,
    
    479 483
             focusedBCId,
    

  • toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs
    ... ... @@ -931,16 +931,24 @@ function shouldVerifySignedState(aAddonType, aLocation) {
    931 931
      *        or undefined if the file wasn't signed.
    
    932 932
      */
    
    933 933
     export var verifyBundleSignedState = async function (aBundle, aAddon) {
    
    934
    -  let pkg = Package.get(aBundle);
    
    935 934
       try {
    
    936
    -    let { signedState, signedTypes } = await pkg.verifySignedState(
    
    937
    -      aAddon.id,
    
    938
    -      aAddon.type,
    
    939
    -      aAddon.location
    
    940
    -    );
    
    941
    -    return { signedState, signedTypes };
    
    942
    -  } finally {
    
    943
    -    pkg.close();
    
    935
    +    let pkg = Package.get(aBundle);
    
    936
    +    try {
    
    937
    +      let { signedState, signedTypes } = await pkg.verifySignedState(
    
    938
    +        aAddon.id,
    
    939
    +        aAddon.type,
    
    940
    +        aAddon.location
    
    941
    +      );
    
    942
    +      return { signedState, signedTypes };
    
    943
    +    } finally {
    
    944
    +      pkg.close();
    
    945
    +    }
    
    946
    +  } catch (e) {
    
    947
    +    logger.warn(`verifyBundleSignedState failed for ${aAddon.id}`, e);
    
    948
    +    if (!shouldVerifySignedState(aAddon.type, aAddon.location)) {
    
    949
    +      return { signedState: AddonManager.SIGNEDSTATE_NOT_REQUIRED };
    
    950
    +    }
    
    951
    +    return { signedState: AddonManager.SIGNEDSTATE_BROKEN };
    
    944 952
       }
    
    945 953
     };
    
    946 954
     
    

  • toolkit/mozapps/extensions/test/xpcshell/test_signed_verify.js
    ... ... @@ -23,6 +23,13 @@ function verifySignatures() {
    23 23
       });
    
    24 24
     }
    
    25 25
     
    
    26
    +async function writeCorruptedXPIFile(extensionId) {
    
    27
    +  let file = AddonTestUtils.getFileForAddon(profileDir, extensionId);
    
    28
    +  // Clear any handles to the file before replacing it; Windows is very picky.
    
    29
    +  Services.obs.notifyObservers(file, "flush-cache-entry");
    
    30
    +  await IOUtils.writeUTF8(file.path, "not a XPI file anymore");
    
    31
    +}
    
    32
    +
    
    26 33
     createAppInfo("xpcshell@xxxxxxxxxxxxxxxxx", "XPCShell", "4", "48");
    
    27 34
     
    
    28 35
     add_setup(async () => {
    
    ... ... @@ -581,3 +588,159 @@ add_task(async function test_xpi_signed_in_or_before_feb_2018() {
    581 588
     
    
    582 589
       ExtensionTestUtils.failOnSchemaWarnings(true);
    
    583 590
     });
    
    591
    +
    
    592
    +add_task(
    
    593
    +  {
    
    594
    +    ...useAMOStageCert(),
    
    595
    +    // This test verifies a behavior that is only hit on builds where the
    
    596
    +    // enterprise policies are enabled (and skipped in build where enterprise
    
    597
    +    // policies are disabled, like in mobile builds).
    
    598
    +    skip_if: () => !Services.policies,
    
    599
    +  },
    
    600
    +  async function test_adminInstallOnly_on_verify_with_invalid_manifest() {
    
    601
    +    const { sinon } = ChromeUtils.importESModule(
    
    602
    +      "resource://testing-common/Sinon.sys.mjs"
    
    603
    +    );
    
    604
    +    const sandbox = sinon.createSandbox();
    
    605
    +
    
    606
    +    const { addon: addon1 } = await promiseInstallFile(
    
    607
    +      do_get_file(`${DATA}/signed1.xpi`)
    
    608
    +    );
    
    609
    +    const { addon: addon2 } = await promiseInstallFile(
    
    610
    +      do_get_file(`${DATA}/long.xpi`)
    
    611
    +    );
    
    612
    +
    
    613
    +    const { XPIExports } = ChromeUtils.importESModule(
    
    614
    +      "resource://gre/modules/addons/XPIExports.sys.mjs"
    
    615
    +    );
    
    616
    +    sinon
    
    617
    +      .stub(XPIExports.XPIInstall, "loadManifestFromFile")
    
    618
    +      .callsFake((_sourceBundle, _location) => {
    
    619
    +        throw new Error("FAKE invalid manifest error");
    
    620
    +      });
    
    621
    +
    
    622
    +    const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => {
    
    623
    +      await verifySignatures();
    
    624
    +    });
    
    625
    +    sandbox.restore();
    
    626
    +
    
    627
    +    // Expect a logged warning for each of the two extensions.
    
    628
    +    AddonTestUtils.checkMessages(messages, {
    
    629
    +      expected: [
    
    630
    +        {
    
    631
    +          message:
    
    632
    +            /XPI_verifySignature Warning on 'test@xxxxxxxxxxxxx': Error: FAKE invalid manifest error/,
    
    633
    +        },
    
    634
    +        {
    
    635
    +          message:
    
    636
    +            /XPI_verifySignature Warning on '123456789.*@somewhere.com': Error: FAKE invalid manifest error/,
    
    637
    +        },
    
    638
    +      ],
    
    639
    +    });
    
    640
    +
    
    641
    +    await addon1.uninstall();
    
    642
    +    await addon2.uninstall();
    
    643
    +  }
    
    644
    +);
    
    645
    +
    
    646
    +add_task(useAMOStageCert(), async function test_broken_file() {
    
    647
    +  await promiseInstallFile(do_get_file(`${DATA}/signed1.xpi`));
    
    648
    +
    
    649
    +  let addon = await promiseAddonByID(ID);
    
    650
    +  Assert.notEqual(addon, null);
    
    651
    +  Assert.equal(addon.appDisabled, false);
    
    652
    +  Assert.equal(addon.isActive, true);
    
    653
    +  Assert.equal(addon.signedState, AddonManager.SIGNEDSTATE_SIGNED);
    
    654
    +
    
    655
    +  await writeCorruptedXPIFile(ID);
    
    656
    +
    
    657
    +  let changedProperties = [];
    
    658
    +  let listener = {
    
    659
    +    onPropertyChanged(addon, properties) {
    
    660
    +      changedProperties.push(...properties);
    
    661
    +    },
    
    662
    +  };
    
    663
    +
    
    664
    +  AddonManager.addAddonListener(listener);
    
    665
    +
    
    666
    +  const disablePromise = promiseAddonEvent("onDisabling");
    
    667
    +  let changes;
    
    668
    +  const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => {
    
    669
    +    changes = await verifySignatures();
    
    670
    +  });
    
    671
    +  await disablePromise;
    
    672
    +
    
    673
    +  Assert.equal(changes.enabled.length, 0);
    
    674
    +  Assert.equal(changes.disabled.length, 1);
    
    675
    +  Assert.equal(changes.disabled[0], ID);
    
    676
    +
    
    677
    +  Assert.deepEqual(
    
    678
    +    changedProperties,
    
    679
    +    ["signedState", "signedTypes", "appDisabled"],
    
    680
    +    "Got onPropertyChanged events for signedState and appDisabled"
    
    681
    +  );
    
    682
    +
    
    683
    +  Assert.ok(addon.appDisabled);
    
    684
    +  Assert.ok(!addon.isActive);
    
    685
    +  Assert.equal(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
    
    686
    +
    
    687
    +  await addon.uninstall();
    
    688
    +  AddonManager.removeAddonListener(listener);
    
    689
    +
    
    690
    +  AddonTestUtils.checkMessages(messages, {
    
    691
    +    expected: [
    
    692
    +      { message: /verifyBundleSignedState failed for test@xxxxxxxxxxxxx/ },
    
    693
    +    ],
    
    694
    +  });
    
    695
    +});
    
    696
    +
    
    697
    +// Verify that verifySignatures() does not change signedState for addons that
    
    698
    +// do not require signatures, even if the underlying file got corrupted.
    
    699
    +add_task(
    
    700
    +  {
    
    701
    +    ...useAMOStageCert(),
    
    702
    +    // # Non-extension add-ons are not supported on Android.
    
    703
    +    skip_if: () => AppConstants.platform == "android",
    
    704
    +  },
    
    705
    +  async function test_broken_file_not_requiring_signatures() {
    
    706
    +    // Note: If dictionaries ever require signatures (bug 1753276), change this
    
    707
    +    // test to another test case where shouldVerifySignedState returns false.
    
    708
    +    let addon = await promiseInstallWebExtension({
    
    709
    +      useAddonManager: true,
    
    710
    +      manifest: {
    
    711
    +        browser_specific_settings: { gecko: { id: "broken@dict" } },
    
    712
    +        dictionaries: { "en-US": "en-US.dic" },
    
    713
    +      },
    
    714
    +      files: { "en-US.dic": "", "en-US.aff": "" },
    
    715
    +    });
    
    716
    +    Assert.equal(addon.signedState, AddonManager.SIGNEDSTATE_NOT_REQUIRED);
    
    717
    +
    
    718
    +    await writeCorruptedXPIFile(addon.id);
    
    719
    +
    
    720
    +    let listener = {
    
    721
    +      onPropertyChanged(_addon) {
    
    722
    +        Assert.ok(false, `Got unexpected onPropertyChanged for ${_addon.id}`);
    
    723
    +      },
    
    724
    +    };
    
    725
    +
    
    726
    +    AddonManager.addAddonListener(listener);
    
    727
    +
    
    728
    +    let changes;
    
    729
    +    const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => {
    
    730
    +      changes = await verifySignatures();
    
    731
    +    });
    
    732
    +    Assert.equal(changes.enabled.length, 0);
    
    733
    +    Assert.equal(changes.disabled.length, 0);
    
    734
    +
    
    735
    +    Assert.equal(addon.appDisabled, false);
    
    736
    +    Assert.equal(addon.isActive, true);
    
    737
    +    Assert.equal(addon.signedState, AddonManager.SIGNEDSTATE_NOT_REQUIRED);
    
    738
    +
    
    739
    +    await addon.uninstall();
    
    740
    +    AddonManager.removeAddonListener(listener);
    
    741
    +
    
    742
    +    AddonTestUtils.checkMessages(messages, {
    
    743
    +      expected: [{ message: /verifyBundleSignedState failed for broken@dict/ }],
    
    744
    +    });
    
    745
    +  }
    
    746
    +);

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