tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_renderer_strings.html (6380B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4 <script src="/tests/SimpleTest/SimpleTest.js"></script>
      5 <link rel="stylesheet" href="/tests/SimpleTest/test.css">
      6 </head>
      7 <body>
      8 <script>
      9 
     10 let gl, ext;
     11 
     12 function getStrings() {
     13  const ret = {
     14    renderer: gl.getParameter(gl.RENDERER),
     15    vendor: gl.getParameter(gl.VENDOR),
     16  };
     17  if (ext) {
     18    ret.unmasked_renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
     19    ret.unmasked_vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
     20  }
     21  return ret;
     22 }
     23 
     24 const RTX3070_R = 'ANGLE (NVIDIA, NVIDIA GeForce RTX 3070 Direct3D11 vs_5_0 ps_5_0, D3D11-27.21.14.5751)';
     25 const RTX3070_V = 'Google Inc.';
     26 const RTX3070_R_SANITIZED = 'ANGLE (NVIDIA, NVIDIA GeForce GTX 980 Direct3D11 vs_5_0 ps_5_0), or similar';
     27 
     28 function expectJsonEqual(was, expected, when) {
     29  if (when) {
     30    when = when + ': ';
     31  } else {
     32    when = '';
     33  }
     34  const wasStr = JSON.stringify(was);
     35  const expectedStr = JSON.stringify(expected);
     36  let str = `${when}Was ${wasStr}`;
     37  const matches = (wasStr == expectedStr);
     38  if (!matches) {
     39    str += `, expected ${expectedStr}`;
     40  }
     41  ok(matches, str);
     42 }
     43 
     44 async function testKnownCiStrings() {
     45  gl = document.createElement('canvas').getContext('webgl');
     46  if (!gl) return;
     47 
     48  await SpecialPowers.pushPrefEnv({'set': [
     49    ['webgl.sanitize-unmasked-renderer', false],
     50  ]});
     51  ext = gl.getExtension('WEBGL_debug_renderer_info');
     52  const was = getStrings();
     53 
     54  const KNOWN_ON_CI = {
     55    renderer: [
     56      'Adreno (TM) 540', // Android
     57      'Adreno (TM) 650', // Android pixel5
     58      'ANGLE (Samsung Xclipse 920) on Vulkan', // Android a55
     59      'llvmpipe', // Linux
     60      'Intel(R) HD Graphics 400', // Mac
     61      'Apple M1', // Mac
     62      'Apple M2', // Mac
     63      'Apple M4', // Mac
     64      'ANGLE (NVIDIA, NVIDIA GeForce 8800 GTX Direct3D11 vs_5_0 ps_5_0)', // Windows
     65    ].map(x => x + ', or similar'),
     66    vendor: [
     67      'Mozilla',
     68    ],
     69    unmasked_renderer: [
     70      'Adreno (TM) 540', // Android
     71      'Adreno (TM) 620', // Android pixel5
     72      'ANGLE (Samsung Xclipse 530) on Vulkan 1.3.231', // Android a55
     73      'llvmpipe (LLVM 10.0.0, 256 bits)', // Linux (Ubuntu 18.04)
     74      'llvmpipe (LLVM 17.0.6, 256 bits)', // Linux (Ubuntu 24.04)
     75      'llvmpipe (LLVM 19.1.1, 256 bits)', // Linux (Ubuntu 24.04.2)
     76      'Intel(R) UHD Graphics 630', // Mac
     77      'Apple M1', // Mac
     78      'Apple M2', // Mac
     79      'Apple M4', // Mac
     80      'ANGLE (NVIDIA, NVIDIA Tesla M60 Direct3D11 vs_5_0 ps_5_0, D3D11-23.21.13.9181)', // Windows
     81      'ANGLE (NVIDIA, NVIDIA Tesla M60 Direct3D11 vs_5_0 ps_5_0, D3D11-30.0.14.7239)', // Windows 11
     82      'ANGLE (NVIDIA, NVIDIA Tesla M60 Direct3D11 vs_5_0 ps_5_0, D3D11-31.0.15.3815)', //Windows 11
     83      'ANGLE (NVIDIA, NVIDIA A10-8Q Direct3D11 vs_5_0 ps_5_0, D3D11-31.0.15.5362)', // Windows 11:Azure
     84    ],
     85    unmasked_vendor: [
     86      'Qualcomm', // Android
     87      'Samsung Electronics Co., Ltd.', // Android
     88      'VMware, Inc.', // Linux
     89      'Mesa', // Linux
     90      'Intel Inc.', // Mac
     91      'Apple', // Mac
     92      'Google Inc. (NVIDIA)', // Windows
     93    ],
     94  };
     95  for (const k in was) {
     96    const wasVal = was[k];
     97    const knownList = KNOWN_ON_CI[k];
     98    ok(knownList.includes(wasVal),
     99       `[ignore if not on CI] getParameter(${k}) -> '${wasVal}' must be in KNOWN_ON_CI`);
    100  }
    101  await SpecialPowers.popPrefEnv();
    102 }
    103 
    104 // -
    105 
    106 async function testPrefBehaviorForExampleRtx3070() {
    107  const canvas = document.createElement('canvas');
    108  gl = canvas.getContext('webgl');
    109  ext = null;
    110  if (!gl) {
    111    todo(gl, 'Get WebGL working here first.');
    112    return;
    113  }
    114 
    115  // -
    116  // Assuming that we're on CI, test against known-good strings.
    117  // If we add machine configs, we'll need to add to these lists.
    118  // This is to avoid situations like bug 1743734, where ANGLE added
    119  // detailed driver version/date to its RENDERER strings, which
    120  // we want to prevent.
    121 
    122  await SpecialPowers.pushPrefEnv({'set': [
    123    ['webgl.override-unmasked-renderer', RTX3070_R],
    124    ['webgl.override-unmasked-vendor', RTX3070_V],
    125  ]});
    126 
    127  // -
    128  // Test disabled
    129 
    130  await SpecialPowers.pushPrefEnv({'set': [
    131    ['webgl.enable-debug-renderer-info', false],
    132  ]});
    133 
    134  ext = gl.getExtension('WEBGL_debug_renderer_info');
    135  ok(!ext,
    136     'When pref disabled: Should not have access to \'WEBGL_debug_renderer_info\'.');
    137 
    138  {
    139    const EXPECTED = {
    140      renderer: RTX3070_R_SANITIZED,
    141      vendor: 'Mozilla',
    142    };
    143    const was = getStrings();
    144    expectJsonEqual(was, EXPECTED, 'v92 behavior w/o ext');
    145  }
    146 
    147  await SpecialPowers.popPrefEnv();
    148 
    149  // -
    150  // Test RFP
    151 
    152  await SpecialPowers.pushPrefEnv({'set': [
    153    ['privacy.resistFingerprinting', true],
    154  ]});
    155 
    156  ext = gl.getExtension('WEBGL_debug_renderer_info');
    157 
    158  {
    159    const EXPECTED = {
    160      renderer: 'Mozilla',
    161      vendor: 'Mozilla',
    162      unmasked_renderer: 'Mozilla',
    163      unmasked_vendor: 'Mozilla',
    164    };
    165    const was = getStrings();
    166    expectJsonEqual(was, EXPECTED, 'RFP behavior');
    167  }
    168 
    169  await SpecialPowers.popPrefEnv();
    170 
    171  // -
    172  // Test default state (v92+)
    173 
    174  ext = gl.getExtension('WEBGL_debug_renderer_info');
    175  ok(ext,
    176     'By default: Should have access to \'WEBGL_debug_renderer_info\'.');
    177 
    178  {
    179    const EXPECTED = {
    180      renderer: RTX3070_R_SANITIZED,
    181      vendor: 'Mozilla',
    182      unmasked_renderer: RTX3070_R_SANITIZED,
    183      unmasked_vendor: RTX3070_V,
    184    };
    185    const was = getStrings();
    186    expectJsonEqual(was, EXPECTED, 'v92 behavior');
    187  }
    188 
    189  // -
    190  // Test v91 behavior
    191 
    192  await SpecialPowers.pushPrefEnv({'set': [
    193    ['webgl.enable-renderer-query', false],
    194  ]});
    195 
    196  {
    197    const EXPECTED = {
    198      renderer: 'Mozilla',
    199      vendor: 'Mozilla',
    200      unmasked_renderer: RTX3070_R_SANITIZED,
    201      unmasked_vendor: RTX3070_V,
    202    };
    203    const was = getStrings();
    204    expectJsonEqual(was, EXPECTED, 'v91 behavior');
    205  }
    206 
    207  // -
    208  // Test v90 behavior
    209 
    210  await SpecialPowers.pushPrefEnv({'set': [
    211    ['webgl.sanitize-unmasked-renderer', false],
    212  ]});
    213 
    214  {
    215    const EXPECTED = {
    216      renderer: 'Mozilla',
    217      vendor: 'Mozilla',
    218      unmasked_renderer: RTX3070_R,
    219      unmasked_vendor: RTX3070_V,
    220    };
    221    const was = getStrings();
    222    expectJsonEqual(was, EXPECTED, 'v90 behavior');
    223  }
    224 }
    225 
    226 // -
    227 
    228 SimpleTest.waitForExplicitFinish();
    229 (async function() {
    230  await testKnownCiStrings();
    231  await testPrefBehaviorForExampleRtx3070();
    232 
    233  ok(true, 'Test complete.');
    234  SimpleTest.finish();
    235 })();
    236 
    237 </script>
    238 </body>
    239 </html>