tor-browser

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

out-of-bounds-uniform-array-access.html (5095B)


      1 <!--
      2 Copyright (c) 2019 The Khronos Group Inc.
      3 Use of this source code is governed by an MIT-style license that can be
      4 found in the LICENSE.txt file.
      5 -->
      6 
      7 <!DOCTYPE html>
      8 <html>
      9 <head>
     10 <meta charset="utf-8">
     11 <title>WebGL out of bounds uniform array access.</title>
     12 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
     13 <script src="../../js/js-test-pre.js"></script>
     14 <script src="../../js/webgl-test-utils.js"> </script>
     15 </head>
     16 <body>
     17 <div id="description"></div>
     18 <canvas id="example" width="128" height="128" style="background: black;">
     19 </canvas>
     20 <div id="console"></div>
     21 <script id="vshader" type="x-shader/x-vertex">
     22 attribute vec4 vPosition;
     23 varying vec4 v_color;
     24 uniform float lineWidth;
     25 uniform int elemMult;
     26 uniform vec4 colorArray[6];
     27 void main()
     28 {
     29    vec2 texcoord = vec2(vPosition.xy * 0.5 + vec2(0.5, 0.5));
     30    int index = int(texcoord.x + texcoord.y * lineWidth) * elemMult;
     31    v_color = colorArray[index];
     32    gl_Position = vPosition;
     33    gl_PointSize = 1.0;
     34 }
     35 </script>
     36 
     37 <script id="fshader" type="x-shader/x-fragment">
     38 precision mediump float;
     39 varying vec4 v_color;
     40 void main()
     41 {
     42  gl_FragColor = v_color;
     43 }
     44 </script>
     45 <script>
     46 "use strict";
     47 debug("Tests a WebGL program that accesses out of bounds uniform array elements");
     48 
     49 var gl;
     50 var gridRes = 127;
     51 var lineWidthLoc;
     52 var elemMultLoc;
     53 var width = 128;
     54 var height = 128;
     55 var pixels = new Uint8Array(width * height * 4);
     56 
     57 var lineWidth = 0;
     58 var elemMult = 0;
     59 
     60 var knownColors = [
     61  1.0, 0.0, 0.0, 1.0,  // Red
     62  0.0, 1.0, 0.0, 1.0,  // Green
     63  0.0, 0.0, 1.0, 1.0,  // Blue
     64  0.0, 1.0, 1.0, 1.0,  // Cyan
     65  1.0, 0.0, 1.0, 1.0,  // Magenta
     66  1.0, 1.0, 0.0, 1.0   // Yellow
     67 ];
     68 
     69 function main() {
     70  var wtu = WebGLTestUtils;
     71  gl = wtu.create3DContext("example");
     72  var program = wtu.setupProgram(
     73      gl,
     74      ['vshader', 'fshader'],
     75      ['vPosition'], [0]);
     76 
     77  // setupQuad produces the geometry we want for a gridRes x gridRes grid
     78  // of points. No interpolation will be performed across the points, so
     79  // according to the WebGL specification for out-of-bounds array accesses,
     80  // we will get exactly the input colors from the uniform colorArray, or
     81  // zero, for each pixel on the canvas.
     82  wtu.setupIndexedQuad(gl, gridRes, 0);
     83  var colorArrayLoc = gl.getUniformLocation(program, "colorArray[0]");
     84  assertMsg(colorArrayLoc != null, "color array uniform should be found");
     85  var colors = new Float32Array(knownColors);
     86  gl.uniform4fv(colorArrayLoc, colors);
     87  lineWidthLoc = gl.getUniformLocation(program, "lineWidth");
     88  elemMultLoc = gl.getUniformLocation(program, "elemMult");
     89  assertMsg(gl.getError() == gl.NO_ERROR, "Should be no errors from setup.");
     90  runOneIteration();
     91 }
     92 
     93 function withinEpsilon(val1, val2) {
     94  return Math.abs(val1 - val2) < 0.0001;
     95 }
     96 
     97 function isKnownColor(r, g, b) {
     98  if (r == 0 && g == 0 && b == 0)
     99    return true;
    100  for (var ii = 0; ii < knownColors.length; ii += 4) {
    101    if (withinEpsilon(r / 255.0, knownColors[ii + 0]) &&
    102        withinEpsilon(g / 255.0, knownColors[ii + 1]) &&
    103        withinEpsilon(b / 255.0, knownColors[ii + 2]))
    104      return true;
    105  }
    106  return false;
    107 }
    108 
    109 function runOneIteration() {
    110  if (elemMult < 2048) {
    111    var ok = true;
    112    var startingLineWidth = lineWidth;
    113    var firstFailingPixel = null;
    114    var firstFailingValue = null;
    115    for (; lineWidth < 2540; lineWidth += 31) {
    116      // Draw
    117      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    118      gl.uniform1f(lineWidthLoc, lineWidth);
    119      gl.uniform1i(elemMultLoc, elemMult);
    120      gl.drawArrays(gl.POINTS, 0, gridRes * gridRes);
    121 
    122      // Read back
    123      gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
    124 
    125      // Verify
    126      for (var y = 0; y < height; ++y) {
    127        for (var x = 0; x < width; ++x) {
    128          if (!isKnownColor(pixels[4 * (width * y + x) + 0],
    129                            pixels[4 * (width * y + x) + 1],
    130                            pixels[4 * (width * y + x) + 2])) {
    131            ok = false;
    132            if (firstFailingPixel == null) {
    133              firstFailingPixel = [x, y];
    134              firstFailingValue = [pixels[4 * (width * y + x) + 0],
    135                                   pixels[4 * (width * y + x) + 1],
    136                                   pixels[4 * (width * y + x) + 2]];
    137            }
    138          }
    139        }
    140      }
    141    }
    142    var endingLineWidth = lineWidth - 31;
    143    lineWidth -= 2540;
    144    if (ok) {
    145      testPassed("Good rendering results for lineWidths " +
    146                 startingLineWidth + "..." + endingLineWidth +
    147                 " at elemMult=" + elemMult);
    148    } else {
    149      testFailed("for lineWidth=" + lineWidth + ", elemMult=" + elemMult +
    150                 ": first failing pixel (" + firstFailingPixel[0] + ", " + firstFailingPixel[1] + ") was (" +
    151                 firstFailingValue[0] + ", " +
    152                 firstFailingValue[1] + ", " +
    153                 firstFailingValue[2] + "), should be (0, 0, 0) or one of known colors");
    154    }
    155    elemMult += 73;
    156    setTimeout(runOneIteration, 0);
    157  } else {
    158    finishTest();
    159  }
    160 }
    161 
    162 main();
    163 
    164 var successfullyParsed = true;
    165 
    166 </script>
    167 </body>
    168 </html>