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

Commits:

5 changed files:

Changes:

  • dom/media/TimeUnits.cpp
    ... ... @@ -80,7 +80,7 @@ TimeUnit TimeUnit::FromSeconds(double aValue, int64_t aBase) {
    80 80
       // base -- we can keep this for some time until we're confident this is
    
    81 81
       // stable.
    
    82 82
       double inBase = aValue * static_cast<double>(aBase);
    
    83
    -  if (std::abs(inBase) >
    
    83
    +  if (std::abs(inBase) >=
    
    84 84
           static_cast<double>(std::numeric_limits<int64_t>::max())) {
    
    85 85
         NS_WARNING(
    
    86 86
             nsPrintfCString("Warning: base %" PRId64
    

  • dom/media/test/crashtests/2014865.html
    1
    +<!DOCTYPE html>
    
    2
    +<html>
    
    3
    +<head><meta charset="utf-8"></head>
    
    4
    +<body>
    
    5
    +<script>
    
    6
    +/*
    
    7
    + * Trigger TimeUnit::FromSeconds boundary overflow via MSE SourceBuffer.remove()
    
    8
    + *
    
    9
    + * Bug in dom/media/TimeUnits.cpp, FromSeconds():
    
    10
    + *   double inBase = aValue * static_cast<double>(aBase);
    
    11
    + *   if (std::abs(inBase) > static_cast<double>(INT64_MAX)) return Infinity;
    
    12
    + *   return TimeUnit(static_cast<int64_t>(std::round(inBase)), aBase);
    
    13
    + *
    
    14
    + * static_cast<double>(INT64_MAX) rounds UP to 2^63. The check uses strict >,
    
    15
    + * so inBase == 2^63 passes. static_cast<int64_t>(round(2^63)) is UNDEFINED
    
    16
    + * BEHAVIOR (2^63 > INT64_MAX). On x86-64 it produces INT64_MIN (negative infinity),
    
    17
    + * corrupting the TimeUnit. The Interval(start, end) constructor asserts start <= end;
    
    18
    + * with end = -Inf and start = 0, the assertion fires.
    
    19
    + */
    
    20
    +
    
    21
    +(async function() {
    
    22
    +  if (!window.MediaSource) return;
    
    23
    +
    
    24
    +  // Find a supported MSE type
    
    25
    +  const types = [
    
    26
    +    'audio/webm; codecs="opus"',
    
    27
    +    'video/webm; codecs="vp8"',
    
    28
    +    'video/webm; codecs="vp9"',
    
    29
    +    'audio/mp4; codecs="mp4a.40.2"',
    
    30
    +    'video/mp4; codecs="avc1.42E01E"',
    
    31
    +    'audio/mp4; codecs="flac"',
    
    32
    +  ];
    
    33
    +  let mimeType = null;
    
    34
    +  for (const t of types) {
    
    35
    +    if (MediaSource.isTypeSupported(t)) { mimeType = t; break; }
    
    36
    +  }
    
    37
    +  if (!mimeType) return;
    
    38
    +
    
    39
    +  // Create MediaSource and SourceBuffer
    
    40
    +  const ms = new MediaSource();
    
    41
    +  const video = document.createElement('video');
    
    42
    +  video.src = URL.createObjectURL(ms);
    
    43
    +  document.body.appendChild(video);
    
    44
    +  await new Promise(r => ms.addEventListener('sourceopen', r));
    
    45
    +  const sb = ms.addSourceBuffer(mimeType);
    
    46
    +
    
    47
    +  // Critical boundary value: 2^63 / 10^6 ≈ 9223372036854.776
    
    48
    +  // This is the value where inBase = value * 10^6 ≈ 2^63 exactly,
    
    49
    +  // which passes the > check but causes UB in static_cast<int64_t>
    
    50
    +  const criticalValue = 9223372036854.776;
    
    51
    +
    
    52
    +  // Set duration large enough to allow the remove
    
    53
    +  try { ms.duration = criticalValue + 1; } catch(e) {}
    
    54
    +
    
    55
    +  // Trigger the bug: remove(0, criticalValue) calls
    
    56
    +  // TimeUnit::FromSeconds(criticalValue) which overflows
    
    57
    +  try {
    
    58
    +    sb.remove(0, criticalValue);
    
    59
    +    await new Promise(r => {
    
    60
    +      sb.addEventListener('updateend', r, { once: true });
    
    61
    +      sb.addEventListener('error', r, { once: true });
    
    62
    +      setTimeout(r, 500);
    
    63
    +    });
    
    64
    +  } catch(e) {}
    
    65
    +
    
    66
    +  // Try a few more boundary values
    
    67
    +  const vals = [
    
    68
    +    Math.pow(2, 63) / 1e6,
    
    69
    +    9223372036854.775,
    
    70
    +    1e15,
    
    71
    +    1e16,
    
    72
    +    Number.MAX_SAFE_INTEGER,
    
    73
    +  ];
    
    74
    +  for (const val of vals) {
    
    75
    +    try {
    
    76
    +      if (ms.readyState !== 'open' || sb.updating) break;
    
    77
    +      ms.duration = Math.abs(val) + 1;
    
    78
    +      sb.remove(0, val);
    
    79
    +      await new Promise(r => {
    
    80
    +        sb.addEventListener('updateend', r, { once: true });
    
    81
    +        sb.addEventListener('error', r, { once: true });
    
    82
    +        setTimeout(r, 300);
    
    83
    +      });
    
    84
    +    } catch(e) {}
    
    85
    +  }
    
    86
    +
    
    87
    +  video.remove();
    
    88
    +})();
    
    89
    +</script>
    
    90
    +</body>
    
    91
    +</html>

  • dom/media/test/crashtests/crashtests.list
    ... ... @@ -188,3 +188,4 @@ load 1905231.webm
    188 188
     load 1917627.mp4
    
    189 189
     skip-if(Android) load audioworkletprocessor-recursion.html
    
    190 190
     load 2014824.html
    
    191
    +load 2014865.html

  • gfx/thebes/gfxHarfBuzzShaper.cpp
    ... ... @@ -1209,9 +1209,6 @@ static void AddOpenTypeFeature(uint32_t aTag, uint32_t aValue, void* aUserArg) {
    1209 1209
      * gfxFontShaper override to initialize the text run using HarfBuzz
    
    1210 1210
      */
    
    1211 1211
     
    
    1212
    -static hb_font_funcs_t* sHBFontFuncs = nullptr;
    
    1213
    -static hb_font_funcs_t* sNominalGlyphFunc = nullptr;
    
    1214
    -static hb_unicode_funcs_t* sHBUnicodeFuncs = nullptr;
    
    1215 1212
     MOZ_RUNINIT static const hb_script_t sMathScript =
    
    1216 1213
         hb_ot_tag_to_script(HB_TAG('m', 'a', 't', 'h'));
    
    1217 1214
     
    
    ... ... @@ -1222,52 +1219,58 @@ bool gfxHarfBuzzShaper::Initialize() {
    1222 1219
       mInitialized = true;
    
    1223 1220
       mCallbackData.mShaper = this;
    
    1224 1221
     
    
    1225
    -  if (!sHBFontFuncs) {
    
    1226
    -    // static function callback pointers, initialized by the first
    
    1227
    -    // harfbuzz shaper used
    
    1228
    -    sHBFontFuncs = hb_font_funcs_create();
    
    1229
    -    hb_font_funcs_set_nominal_glyph_func(sHBFontFuncs, HBGetNominalGlyph,
    
    1230
    -                                         nullptr, nullptr);
    
    1231
    -    hb_font_funcs_set_nominal_glyphs_func(sHBFontFuncs, HBGetNominalGlyphs,
    
    1232
    -                                          nullptr, nullptr);
    
    1233
    -    hb_font_funcs_set_variation_glyph_func(sHBFontFuncs, HBGetVariationGlyph,
    
    1234
    -                                           nullptr, nullptr);
    
    1235
    -    hb_font_funcs_set_glyph_h_advance_func(sHBFontFuncs, HBGetGlyphHAdvance,
    
    1236
    -                                           nullptr, nullptr);
    
    1237
    -    hb_font_funcs_set_glyph_h_advances_func(sHBFontFuncs, HBGetGlyphHAdvances,
    
    1238
    -                                            nullptr, nullptr);
    
    1239
    -    hb_font_funcs_set_glyph_v_advance_func(sHBFontFuncs, HBGetGlyphVAdvance,
    
    1240
    -                                           nullptr, nullptr);
    
    1241
    -    hb_font_funcs_set_glyph_v_origin_func(sHBFontFuncs, HBGetGlyphVOrigin,
    
    1242
    -                                          nullptr, nullptr);
    
    1243
    -    hb_font_funcs_set_glyph_extents_func(sHBFontFuncs, HBGetGlyphExtents,
    
    1244
    -                                         nullptr, nullptr);
    
    1245
    -    hb_font_funcs_set_glyph_contour_point_func(sHBFontFuncs, HBGetContourPoint,
    
    1222
    +  // Function callback pointers; these are local statics to ensure thread-safe
    
    1223
    +  // initialization on first use.
    
    1224
    +  static hb_font_funcs_t* sHBFontFuncs = [] {
    
    1225
    +    auto* funcs = hb_font_funcs_create();
    
    1226
    +    hb_font_funcs_set_nominal_glyph_func(funcs, HBGetNominalGlyph, nullptr,
    
    1227
    +                                         nullptr);
    
    1228
    +    hb_font_funcs_set_nominal_glyphs_func(funcs, HBGetNominalGlyphs, nullptr,
    
    1229
    +                                          nullptr);
    
    1230
    +    hb_font_funcs_set_variation_glyph_func(funcs, HBGetVariationGlyph, nullptr,
    
    1231
    +                                           nullptr);
    
    1232
    +    hb_font_funcs_set_glyph_h_advance_func(funcs, HBGetGlyphHAdvance, nullptr,
    
    1233
    +                                           nullptr);
    
    1234
    +    hb_font_funcs_set_glyph_h_advances_func(funcs, HBGetGlyphHAdvances, nullptr,
    
    1235
    +                                            nullptr);
    
    1236
    +    hb_font_funcs_set_glyph_v_advance_func(funcs, HBGetGlyphVAdvance, nullptr,
    
    1237
    +                                           nullptr);
    
    1238
    +    hb_font_funcs_set_glyph_v_origin_func(funcs, HBGetGlyphVOrigin, nullptr,
    
    1239
    +                                          nullptr);
    
    1240
    +    hb_font_funcs_set_glyph_extents_func(funcs, HBGetGlyphExtents, nullptr,
    
    1241
    +                                         nullptr);
    
    1242
    +    hb_font_funcs_set_glyph_contour_point_func(funcs, HBGetContourPoint,
    
    1246 1243
                                                    nullptr, nullptr);
    
    1247
    -    hb_font_funcs_set_glyph_h_kerning_func(sHBFontFuncs, HBGetHKerning, nullptr,
    
    1244
    +    hb_font_funcs_set_glyph_h_kerning_func(funcs, HBGetHKerning, nullptr,
    
    1248 1245
                                                nullptr);
    
    1249
    -    hb_font_funcs_make_immutable(sHBFontFuncs);
    
    1250
    -
    
    1251
    -    sNominalGlyphFunc = hb_font_funcs_create();
    
    1252
    -    hb_font_funcs_set_nominal_glyph_func(sNominalGlyphFunc, HBGetNominalGlyph,
    
    1253
    -                                         nullptr, nullptr);
    
    1254
    -    hb_font_funcs_make_immutable(sNominalGlyphFunc);
    
    1255
    -
    
    1256
    -    sHBUnicodeFuncs = hb_unicode_funcs_create(hb_unicode_funcs_get_empty());
    
    1257
    -    hb_unicode_funcs_set_mirroring_func(sHBUnicodeFuncs, HBGetMirroring,
    
    1258
    -                                        nullptr, nullptr);
    
    1259
    -    hb_unicode_funcs_set_script_func(sHBUnicodeFuncs, HBGetScript, nullptr,
    
    1260
    -                                     nullptr);
    
    1261
    -    hb_unicode_funcs_set_general_category_func(
    
    1262
    -        sHBUnicodeFuncs, HBGetGeneralCategory, nullptr, nullptr);
    
    1263
    -    hb_unicode_funcs_set_combining_class_func(
    
    1264
    -        sHBUnicodeFuncs, HBGetCombiningClass, nullptr, nullptr);
    
    1265
    -    hb_unicode_funcs_set_compose_func(sHBUnicodeFuncs, HBUnicodeCompose,
    
    1266
    -                                      nullptr, nullptr);
    
    1267
    -    hb_unicode_funcs_set_decompose_func(sHBUnicodeFuncs, HBUnicodeDecompose,
    
    1268
    -                                        nullptr, nullptr);
    
    1269
    -    hb_unicode_funcs_make_immutable(sHBUnicodeFuncs);
    
    1270
    -  }
    
    1246
    +    hb_font_funcs_make_immutable(funcs);
    
    1247
    +    return funcs;
    
    1248
    +  }();
    
    1249
    +
    
    1250
    +  static hb_font_funcs_t* sNominalGlyphFunc = [] {
    
    1251
    +    auto* funcs = hb_font_funcs_create();
    
    1252
    +    hb_font_funcs_set_nominal_glyph_func(funcs, HBGetNominalGlyph, nullptr,
    
    1253
    +                                         nullptr);
    
    1254
    +    hb_font_funcs_make_immutable(funcs);
    
    1255
    +    return funcs;
    
    1256
    +  }();
    
    1257
    +
    
    1258
    +  static hb_unicode_funcs_t* sHBUnicodeFuncs = [] {
    
    1259
    +    auto* funcs = hb_unicode_funcs_create(hb_unicode_funcs_get_empty());
    
    1260
    +    hb_unicode_funcs_set_mirroring_func(funcs, HBGetMirroring, nullptr,
    
    1261
    +                                        nullptr);
    
    1262
    +    hb_unicode_funcs_set_script_func(funcs, HBGetScript, nullptr, nullptr);
    
    1263
    +    hb_unicode_funcs_set_general_category_func(funcs, HBGetGeneralCategory,
    
    1264
    +                                               nullptr, nullptr);
    
    1265
    +    hb_unicode_funcs_set_combining_class_func(funcs, HBGetCombiningClass,
    
    1266
    +                                              nullptr, nullptr);
    
    1267
    +    hb_unicode_funcs_set_compose_func(funcs, HBUnicodeCompose, nullptr,
    
    1268
    +                                      nullptr);
    
    1269
    +    hb_unicode_funcs_set_decompose_func(funcs, HBUnicodeDecompose, nullptr,
    
    1270
    +                                        nullptr);
    
    1271
    +    hb_unicode_funcs_make_immutable(funcs);
    
    1272
    +    return funcs;
    
    1273
    +  }();
    
    1271 1274
     
    
    1272 1275
       gfxFontEntry* entry = mFont->GetFontEntry();
    
    1273 1276
       if (!mUseFontGetGlyph) {
    
    ... ... @@ -1314,23 +1317,23 @@ bool gfxHarfBuzzShaper::Initialize() {
    1314 1317
       hb_buffer_set_cluster_level(mBuffer,
    
    1315 1318
                                   HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
    
    1316 1319
     
    
    1317
    -  auto* funcs =
    
    1318
    -      mFont->GetFontEntry()->HasFontTable(TRUETYPE_TAG('C', 'F', 'F', ' '))
    
    1319
    -          ? sNominalGlyphFunc
    
    1320
    -          : sHBFontFuncs;
    
    1321
    -  mHBFont = CreateHBFont(mFont, funcs, &mCallbackData);
    
    1320
    +  bool isCFF =
    
    1321
    +      mFont->GetFontEntry()->HasFontTable(TRUETYPE_TAG('C', 'F', 'F', ' '));
    
    1322
    +  auto* funcs = isCFF ? sNominalGlyphFunc : sHBFontFuncs;
    
    1323
    +  mHBFont = CreateHBFont(mFont, funcs, &mCallbackData, isCFF);
    
    1322 1324
     
    
    1323 1325
       return true;
    
    1324 1326
     }
    
    1325 1327
     
    
    1326 1328
     hb_font_t* gfxHarfBuzzShaper::CreateHBFont(gfxFont* aFont,
    
    1327 1329
                                                hb_font_funcs_t* aFontFuncs,
    
    1328
    -                                           FontCallbackData* aCallbackData) {
    
    1330
    +                                           FontCallbackData* aCallbackData,
    
    1331
    +                                           bool aCreateSubfont) {
    
    1329 1332
       auto face(aFont->GetFontEntry()->GetHBFace());
    
    1330 1333
       hb_font_t* result = hb_font_create(face);
    
    1331 1334
     
    
    1332 1335
       if (aFontFuncs && aCallbackData) {
    
    1333
    -    if (aFontFuncs == sNominalGlyphFunc) {
    
    1336
    +    if (aCreateSubfont) {
    
    1334 1337
           hb_font_t* subfont = hb_font_create_sub_font(result);
    
    1335 1338
           hb_font_destroy(result);
    
    1336 1339
           result = subfont;
    

  • gfx/thebes/gfxHarfBuzzShaper.h
    ... ... @@ -95,7 +95,8 @@ class gfxHarfBuzzShaper : public gfxFontShaper {
    95 95
       // bounds, etc; if not, the built-in hb_ot font functions will be used.
    
    96 96
       static hb_font_t* CreateHBFont(gfxFont* aFont,
    
    97 97
                                      hb_font_funcs_t* aFontFuncs = nullptr,
    
    98
    -                                 FontCallbackData* aCallbackData = nullptr);
    
    98
    +                                 FontCallbackData* aCallbackData = nullptr,
    
    99
    +                                 bool aCreateSubfont = false);
    
    99 100
     
    
    100 101
       hb_font_t* GetHBFont() const { return mHBFont; }
    
    101 102
       hb_face_t* GetHBFace() const { return hb_font_get_face(mHBFont); }