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

[tor-commits] [Git][tpo/applications/mullvad-browser][mullvad-browser-153.2.0esr-16.0-1] 4 commits: Bug 2045435 - Prune dying entries from wasm::Realm::instances_ during sweeping. r=jpages



Title: GitLab

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

Commits:

  • 641493ef
    by Yury Delendik at 2026-09-01T16:51:37+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
    
  • 13e8e72e
    by Ting-Yu Lin at 2026-09-01T16:51:38+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
    
  • 7ce0a5f6
    by Ting-Yu Lin at 2026-09-01T16:51:38+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
    
  • 1b03bab9
    by Iain Ireland at 2026-09-01T16:51:39+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
    

8 changed files:

Changes:

  • js/src/gc/GCRuntime.h
    ... ... @@ -999,6 +999,7 @@ class GCRuntime {
    999 999
       void updateAtomsBitmap();
    
    1000 1000
       void sweepCCWrappers();
    
    1001 1001
       void sweepRealmGlobals();
    
    1002
    +  void sweepWasmInstances();
    
    1002 1003
       void sweepEmbeddingWeakPointers(JS::GCContext* gcx);
    
    1003 1004
       void sweepMisc();
    
    1004 1005
       void sweepCompressionTasks();
    

  • js/src/gc/Sweeping.cpp
    ... ... @@ -1387,6 +1387,13 @@ void GCRuntime::sweepRealmGlobals() {
    1387 1387
       }
    
    1388 1388
     }
    
    1389 1389
     
    
    1390
    +void GCRuntime::sweepWasmInstances() {
    
    1391
    +  for (SweepGroupRealmsIter r(this); !r.done(); r.next()) {
    
    1392
    +    AutoSetThreadIsSweeping threadIsSweeping(r->zone());
    
    1393
    +    r->wasm.traceWeakInstances();
    
    1394
    +  }
    
    1395
    +}
    
    1396
    +
    
    1390 1397
     void GCRuntime::sweepMisc() {
    
    1391 1398
       SweepingTracer trc(rt);
    
    1392 1399
       for (SweepGroupRealmsIter r(this); !r.done(); r.next()) {
    
    ... ... @@ -1743,6 +1750,11 @@ IncrementalProgress GCRuntime::beginSweepingSweepGroup(JS::GCContext* gcx,
    1743 1750
       // This must happen before updating embedding weak pointers.
    
    1744 1751
       sweepRealmGlobals();
    
    1745 1752
     
    
    1753
    +  // Prune dying wasm instances from each realm's weak instance list now, at the
    
    1754
    +  // start of sweeping, before the mutator can observe them via the (now no-op)
    
    1755
    +  // instances() read barrier during later incremental slices.
    
    1756
    +  sweepWasmInstances();
    
    1757
    +
    
    1746 1758
       sweepEmbeddingWeakPointers(gcx);
    
    1747 1759
     
    
    1748 1760
       maybeWriteCoverageAndSpew();
    

  • 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
    ... ... @@ -3234,7 +3234,9 @@ bool JSStructuredCloneReader::startReadUnchecked(
    3234 3234
         }
    
    3235 3235
     
    
    3236 3236
         case SCTAG_REGEXP_OBJECT: {
    
    3237
    -      if ((data & RegExpFlag::AllFlags) != data) {
    
    3237
    +      // Reject invalid flags. /u and /v are mutually exclusive.
    
    3238
    +      if ((data & RegExpFlag::AllFlags) != data ||
    
    3239
    +          ((data & RegExpFlag::Unicode) && (data & RegExpFlag::UnicodeSets))) {
    
    3238 3240
             JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
    
    3239 3241
                                       JSMSG_SC_BAD_SERIALIZED_DATA, "regexp");
    
    3240 3242
             return false;
    

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

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

  • 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>

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