2010-12-28 Zhenyao Mo <zmo@google.com>
authorzmo@google.com <zmo@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Jan 2011 19:33:58 +0000 (19:33 +0000)
committerzmo@google.com <zmo@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Jan 2011 19:33:58 +0000 (19:33 +0000)
        Reviewed by Kenneth Russell.

        Must generate INVALID_VALUE errors for strings containing out-of-range characters
        https://bugs.webkit.org/show_bug.cgi?id=50929

        * html/canvas/WebGLRenderingContext.cpp: Validate characters according to GLSL ES 1.0 spec section 3.1.
        (WebCore::WebGLRenderingContext::bindAttribLocation):
        (WebCore::WebGLRenderingContext::getAttribLocation):
        (WebCore::WebGLRenderingContext::getUniformLocation):
        (WebCore::WebGLRenderingContext::shaderSource):
        (WebCore::WebGLRenderingContext::validateString): Helper function to perform the character validation.
        * html/canvas/WebGLRenderingContext.h: Declare validateString().
2010-12-28  Zhenyao Mo  <zmo@google.com>

        Reviewed by Kenneth Russell.

        Must generate INVALID_VALUE errors for strings containing out-of-range characters
        https://bugs.webkit.org/show_bug.cgi?id=50929

        * fast/canvas/webgl/invalid-passed-params-expected.txt: Add test cases for invalid characters.
        * fast/canvas/webgl/invalid-passed-params.html: Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@75175 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/canvas/webgl/invalid-passed-params-expected.txt
LayoutTests/fast/canvas/webgl/invalid-passed-params.html
WebCore/ChangeLog
WebCore/html/canvas/WebGLRenderingContext.cpp
WebCore/html/canvas/WebGLRenderingContext.h

index 388d5e3..90a1001 100644 (file)
@@ -1,3 +1,13 @@
+2010-12-28  Zhenyao Mo  <zmo@google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Must generate INVALID_VALUE errors for strings containing out-of-range characters
+        https://bugs.webkit.org/show_bug.cgi?id=50929
+
+        * fast/canvas/webgl/invalid-passed-params-expected.txt: Add test cases for invalid characters.
+        * fast/canvas/webgl/invalid-passed-params.html: Ditto.
+
 2011-01-06  Abhishek Arya  <inferno@chromium.org>
 
         Reviewed by Alexey Proskuryakov.
index c7524cc..793f499 100644 (file)
@@ -2,16 +2,19 @@ Test for invalid passed parameters
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
+
 Test createShader()
 PASS context.createShader(context.FRAGMENT_SHADER) generated expected GL error: NO_ERROR.
 PASS context.createShader(context.VERTEX_SHADER) generated expected GL error: NO_ERROR.
 PASS context.createShader(0) generated expected GL error: INVALID_ENUM.
 PASS context.createShader(context.TRIANGLES) generated expected GL error: INVALID_ENUM.
+
 Test clear()
 PASS context.clear(desktopGL['ACCUM_BUFFER_BIT']) generated expected GL error: INVALID_VALUE.
 PASS context.clear(desktopGL['ACCUM_BUFFER_BIT'] | context.COLOR_BUFFER_BIT) generated expected GL error: INVALID_VALUE.
 PASS context.clear(desktopGL['ACCUM_BUFFER_BIT'] | context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT | context.STENCIL_BUFFER_BIT) generated expected GL error: INVALID_VALUE.
 PASS context.clear(context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT | context.STENCIL_BUFFER_BIT) generated expected GL error: NO_ERROR.
+
 Test bufferData()
 PASS context.bindBuffer(context.ARRAY_BUFFER, buffer) generated expected GL error: NO_ERROR.
 PASS context.bufferData(context.ARRAY_BUFFER, 16, context.STREAM_DRAW) generated expected GL error: NO_ERROR.
@@ -23,6 +26,7 @@ PASS context.bufferData(context.ARRAY_BUFFER, 16, desktopGL['STATIC_READ']) gene
 PASS context.bufferData(context.ARRAY_BUFFER, 16, desktopGL['STATIC_COPY']) generated expected GL error: INVALID_ENUM.
 PASS context.bufferData(context.ARRAY_BUFFER, 16, desktopGL['DYNAMIC_READ']) generated expected GL error: INVALID_ENUM.
 PASS context.bufferData(context.ARRAY_BUFFER, 16, desktopGL['DYNAMIC_COPY']) generated expected GL error: INVALID_ENUM.
+
 Test {copy}Tex{Sub}Image2D with negative offset/width/height
 PASS context.bindTexture(context.TEXTURE_2D, tex) generated expected GL error: NO_ERROR.
 PASS context.texImage2D(context.TEXTURE_2D, 0, context.RGBA, -16, -16, 0, context.RGBA, context.UNSIGNED_BYTE, null) generated expected GL error: INVALID_VALUE.
@@ -35,17 +39,61 @@ PASS context.copyTexImage2D(context.TEXTURE_2D, 0, context.RGBA, 0, 0, 16, 16, 0
 PASS context.copyTexSubImage2D(context.TEXTURE_2D, 0, -1, -1, 0, 0, 2, 2) generated expected GL error: INVALID_VALUE.
 PASS context.copyTexSubImage2D(context.TEXTURE_2D, 0, 0, 0, 0, 0, -1, -1) generated expected GL error: INVALID_VALUE.
 PASS context.copyTexSubImage2D(context.TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2) generated expected GL error: NO_ERROR.
+
 Test renderbufferStorage() with negative width/height
 PASS context.bindRenderbuffer(context.RENDERBUFFER, renderbuffer) generated expected GL error: NO_ERROR.
 PASS context.renderbufferStorage(context.RENDERBUFFER, context.RGBA4, -2, -2) generated expected GL error: INVALID_VALUE.
 PASS context.renderbufferStorage(context.RENDERBUFFER, context.RGBA4, 16, 16) generated expected GL error: NO_ERROR.
+
 Test scissor() with negative width/height
 PASS context.scissor(0, 0, -2, -2) generated expected GL error: INVALID_VALUE.
 PASS context.scissor(0, 0, 16, 16) generated expected GL error: NO_ERROR.
+
 Test viewport() with negative width/height
 PASS context.viewport(0, 0, -2, -2) generated expected GL error: INVALID_VALUE.
 PASS context.viewport(0, 0, 16, 16) generated expected GL error: NO_ERROR.
 
+Set up a program to test invalid characters
+PASS context.getError() is context.NO_ERROR
+PASS context.getError() is context.NO_ERROR
+PASS context.getProgramParameter(program, context.LINK_STATUS) is true
+PASS context.getError() is context.NO_ERROR
+PASS context.getError() is context.NO_ERROR
+PASS context.getError() is context.NO_ERROR
+PASS context.getError() is context.NO_ERROR
+
+Test shaderSource() with invalid characters
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+
+Test bindAttribLocation() with invalid characters
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+
+Test getAttribLocation() with invalid characters
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+
+Test getUniformLocation() with invalid characters
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+PASS context.getError() is context.INVALID_VALUE
+
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 3b49cc5..04c096e 100644 (file)
@@ -14,18 +14,21 @@ description("Test for invalid passed parameters");
 
 var context = create3DContext();
 
+debug("");
 debug("Test createShader()");
 shouldGenerateGLError(context, context.NO_ERROR, "context.createShader(context.FRAGMENT_SHADER)");
 shouldGenerateGLError(context, context.NO_ERROR, "context.createShader(context.VERTEX_SHADER)");
 shouldGenerateGLError(context, context.INVALID_ENUM, "context.createShader(0)");
 shouldGenerateGLError(context, context.INVALID_ENUM, "context.createShader(context.TRIANGLES)");
 
+debug("");
 debug("Test clear()");
 shouldGenerateGLError(context, context.INVALID_VALUE, "context.clear(desktopGL['ACCUM_BUFFER_BIT'])");
 shouldGenerateGLError(context, context.INVALID_VALUE, "context.clear(desktopGL['ACCUM_BUFFER_BIT'] | context.COLOR_BUFFER_BIT)");
 shouldGenerateGLError(context, context.INVALID_VALUE, "context.clear(desktopGL['ACCUM_BUFFER_BIT'] | context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT | context.STENCIL_BUFFER_BIT)");
 shouldGenerateGLError(context, context.NO_ERROR, "context.clear(context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT | context.STENCIL_BUFFER_BIT)");
 
+debug("");
 debug("Test bufferData()");
 var buffer = context.createBuffer();
 shouldGenerateGLError(context, context.NO_ERROR, "context.bindBuffer(context.ARRAY_BUFFER, buffer)");
@@ -39,6 +42,7 @@ shouldGenerateGLError(context, context.INVALID_ENUM, "context.bufferData(context
 shouldGenerateGLError(context, context.INVALID_ENUM, "context.bufferData(context.ARRAY_BUFFER, 16, desktopGL['DYNAMIC_READ'])");
 shouldGenerateGLError(context, context.INVALID_ENUM, "context.bufferData(context.ARRAY_BUFFER, 16, desktopGL['DYNAMIC_COPY'])");
 
+debug("");
 debug("Test {copy}Tex{Sub}Image2D with negative offset/width/height");
 var tex = context.createTexture();
 var pixels = new Uint8Array(2 * 2 * 4);
@@ -54,20 +58,90 @@ shouldGenerateGLError(context, context.INVALID_VALUE, "context.copyTexSubImage2D
 shouldGenerateGLError(context, context.INVALID_VALUE, "context.copyTexSubImage2D(context.TEXTURE_2D, 0, 0, 0, 0, 0, -1, -1)");
 shouldGenerateGLError(context, context.NO_ERROR, "context.copyTexSubImage2D(context.TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2)");
 
+debug("");
 debug("Test renderbufferStorage() with negative width/height");
 var renderbuffer = context.createRenderbuffer();
 shouldGenerateGLError(context, context.NO_ERROR, "context.bindRenderbuffer(context.RENDERBUFFER, renderbuffer)");
 shouldGenerateGLError(context, context.INVALID_VALUE, "context.renderbufferStorage(context.RENDERBUFFER, context.RGBA4, -2, -2)");
 shouldGenerateGLError(context, context.NO_ERROR, "context.renderbufferStorage(context.RENDERBUFFER, context.RGBA4, 16, 16)");
 
+debug("");
 debug("Test scissor() with negative width/height");
 shouldGenerateGLError(context, context.INVALID_VALUE, "context.scissor(0, 0, -2, -2)");
 shouldGenerateGLError(context, context.NO_ERROR, "context.scissor(0, 0, 16, 16)");
 
+debug("");
 debug("Test viewport() with negative width/height");
 shouldGenerateGLError(context, context.INVALID_VALUE, "context.viewport(0, 0, -2, -2)");
 shouldGenerateGLError(context, context.NO_ERROR, "context.viewport(0, 0, 16, 16)");
 
+debug("");
+debug("Set up a program to test invalid characters");
+var invalidSet = ['"', '$', '`', '@', '\\', "'"];
+var validUniformName = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890";
+var validAttribName = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+var validShaderSource = "uniform float " + validUniformName + ";\n"
+                        + "varying float " + validAttribName + ";\n"
+                        + "void main() {\n"
+                        + validAttribName  + " = " + validUniformName + ";\n"
+                        + "gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }\n";
+                        + "//.+-/*%<>[](){}^|&~=!:;,?# ";
+var vShader = context.createShader(context.VERTEX_SHADER);
+context.shaderSource(vShader, validShaderSource);
+context.compileShader(vShader);
+shouldBe("context.getError()", "context.NO_ERROR");
+var fShader = context.createShader(context.FRAGMENT_SHADER);
+context.shaderSource(fShader, "precision highp float;\n"
+                              + "varying float " + validAttribName + ";\n"
+                              + "void main() {\n"
+                              + "gl_FragColor = vec4(" + validAttribName + ", 0.0, 0.0, 1.0); }");
+context.compileShader(fShader);
+shouldBe("context.getError()", "context.NO_ERROR");
+var program = context.createProgram();
+context.attachShader(program, vShader);
+context.attachShader(program, fShader);
+context.linkProgram(program);
+shouldBeTrue("context.getProgramParameter(program, context.LINK_STATUS)");
+shouldBe("context.getError()", "context.NO_ERROR");
+context.bindAttribLocation(program, 1, validAttribName);
+shouldBe("context.getError()", "context.NO_ERROR");
+context.getAttribLocation(program, validAttribName);
+shouldBe("context.getError()", "context.NO_ERROR");
+context.getUniformLocation(program, validUniformName);
+shouldBe("context.getError()", "context.NO_ERROR");
+
+debug("");
+debug("Test shaderSource() with invalid characters");
+for (var i = 0; i < invalidSet.length; ++i) {
+  var invalidShaderSource = validShaderSource + "\n//" + invalidSet[i];
+  context.shaderSource(vShader, invalidShaderSource);
+  shouldBe("context.getError()", "context.INVALID_VALUE");
+}
+
+debug("");
+debug("Test bindAttribLocation() with invalid characters");
+for (var i = 0; i < invalidSet.length; ++i) {
+  var invalidName = validAttribName + invalidSet[i];
+  context.bindAttribLocation(program, 1, invalidName);
+  shouldBe("context.getError()", "context.INVALID_VALUE");
+}
+
+debug("");
+debug("Test getAttribLocation() with invalid characters");
+for (var i = 0; i < invalidSet.length; ++i) {
+  var invalidName = validAttribName + invalidSet[i];
+  context.getAttribLocation(program, invalidName);
+  shouldBe("context.getError()", "context.INVALID_VALUE");
+}
+
+debug("");
+debug("Test getUniformLocation() with invalid characters");
+for (var i = 0; i < invalidSet.length; ++i) {
+  var invalidName = validUniformName + invalidSet[i];
+  context.getUniformLocation(program, invalidName);
+  shouldBe("context.getError()", "context.INVALID_VALUE");
+}
+
 debug("")
 successfullyParsed = true;
 </script>
index 9065590..da9f6a4 100644 (file)
@@ -1,3 +1,18 @@
+2010-12-28  Zhenyao Mo  <zmo@google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Must generate INVALID_VALUE errors for strings containing out-of-range characters
+        https://bugs.webkit.org/show_bug.cgi?id=50929
+
+        * html/canvas/WebGLRenderingContext.cpp: Validate characters according to GLSL ES 1.0 spec section 3.1.
+        (WebCore::WebGLRenderingContext::bindAttribLocation):
+        (WebCore::WebGLRenderingContext::getAttribLocation):
+        (WebCore::WebGLRenderingContext::getUniformLocation):
+        (WebCore::WebGLRenderingContext::shaderSource):
+        (WebCore::WebGLRenderingContext::validateString): Helper function to perform the character validation.
+        * html/canvas/WebGLRenderingContext.h: Declare validateString().
+
 2011-01-06  Yong Li  <yoli@rim.com>
 
         Reviewed by Adam Barth.
index d0c5397..8c14bda 100644 (file)
@@ -86,6 +86,21 @@ namespace {
         *clippedRange = range;
     }
 
+    // Return true if a character belongs to the ASCII subset as defined in
+    // GLSL ES 1.0 spec section 3.1.
+    bool validateCharacter(unsigned char c)
+    {
+        // Printing characters are valid except " $ ` @ \ ' DEL.
+        if (c >= 32 && c <= 126
+            && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
+            return true;
+        // Horizontal tab, line feed, vertical tab, form feed, carriage return
+        // are also valid.
+        if (c >= 9 && c <= 13)
+            return true;
+        return false;
+    }
+
 } // namespace anonymous
 
 class WebGLStateRestorer {
@@ -310,6 +325,8 @@ void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, unsigned l
     UNUSED_PARAM(ec);
     if (isContextLost() || !validateWebGLObject(program))
         return;
+    if (!validateString(name))
+        return;
     m_context->bindAttribLocation(objectOrZero(program), index, name);
     cleanupAfterGraphicsCall(false);
 }
@@ -1460,6 +1477,8 @@ int WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String
 {
     if (isContextLost())
         return -1;
+    if (!validateString(name))
+        return -1;
     return m_context->getAttribLocation(objectOrZero(program), name);
 }
 
@@ -2085,6 +2104,8 @@ PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGL
     UNUSED_PARAM(ec);
     if (isContextLost() || !validateWebGLObject(program))
         return 0;
+    if (!validateString(name))
+        return 0;
     WebGLStateRestorer(this, false);
     long uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
     if (uniformLocation == -1)
@@ -2469,6 +2490,8 @@ void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& stri
     UNUSED_PARAM(ec);
     if (isContextLost() || !validateWebGLObject(shader))
         return;
+    if (!validateString(string))
+        return;
     m_context->shaderSource(objectOrZero(shader), string);
     cleanupAfterGraphicsCall(false);
 }
@@ -3704,6 +3727,17 @@ bool WebGLRenderingContext::validateSize(long x, long y)
     return true;
 }
 
+bool WebGLRenderingContext::validateString(const String& string)
+{
+    for (size_t i = 0; i < string.length(); ++i) {
+        if (!validateCharacter(string[i])) {
+            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+            return false;
+        }
+    }
+    return true;
+}
+
 bool WebGLRenderingContext::validateTexFuncFormatAndType(unsigned long format, unsigned long type)
 {
     switch (format) {
index 1e867d6..554f346 100644 (file)
@@ -515,6 +515,10 @@ public:
     // Generate GL error and return false for negative inputs; otherwise, return true.
     bool validateSize(long x, long y);
 
+    // Helper function to check if all characters in the string belong to the
+    // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
+    bool validateString(const String&);
+
     // Helper function to check target and texture bound to the target.
     // Generate GL errors and return 0 if target is invalid or texture bound is
     // null.  Otherwise, return the texture bound to the target.