Bug 683710: added stripping of comments from shader sources before compiling and check for illegal characters, mostly from webkit code r=bjacob
authorDoug Sherk <dsherk@mozilla.com>
Wed, 07 Sep 2011 17:17:44 -0400
changeset 76853 d04d43c81294ce6073b9cb6c622886e575a27d1f
parent 76852 67e54020dce568e2c2ba7590b54f285863ed7371
child 76854 3208bcc1eaf915991e9ea7a3c85c6c5e77b5a8db
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersbjacob
bugs683710, 680722
milestone9.0a1
Bug 683710: added stripping of comments from shader sources before compiling and check for illegal characters, mostly from webkit code r=bjacob This code is copied mostly from WebKit. It strips out comments from shader source code before actually compiling it, so that the comments can have illegal characters. It was benchmarked and it was noted that a test attached to the bug ticket took about twice as long with these changes. This includes the patch from bug 680722 to check for illegal characters.
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLContextValidate.cpp
content/canvas/src/WebGLValidateStrings.h
content/canvas/test/webgl/failing_tests_linux.txt
content/canvas/test/webgl/failing_tests_mac.txt
content/canvas/test/webgl/failing_tests_windows.txt
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -497,17 +497,19 @@ protected:
     PRBool ValidateFaceEnum(WebGLenum face, const char *info);
     PRBool ValidateBufferUsageEnum(WebGLenum target, const char *info);
     PRBool ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
                                       PRUint32 *texelSize, const char *info);
     PRBool ValidateDrawModeEnum(WebGLenum mode, const char *info);
     PRBool ValidateAttribIndex(WebGLuint index, const char *info);
     PRBool ValidateStencilParamsForDrawCall();
     
-    bool  ValidateGLSLIdentifier(const nsAString& name, const char *info);
+    bool ValidateGLSLVariableName(const nsAString& name, const char *info);
+    bool ValidateGLSLCharacter(PRUnichar c);
+    bool ValidateGLSLString(const nsAString& string, const char *info);
 
     static PRUint32 GetTexelSize(WebGLenum format, WebGLenum type);
 
     void Invalidate();
     void DestroyResourcesAndContext();
 
     void MakeContextCurrent() { gl->MakeCurrent(); }
 
@@ -1361,44 +1363,44 @@ public:
     PRBool Deleted() { return mDeleted && mAttachCount == 0; }
     WebGLuint GLName() { return mName; }
     WebGLenum ShaderType() { return mType; }
 
     PRUint32 AttachCount() { return mAttachCount; }
     void IncrementAttachCount() { mAttachCount++; }
     void DecrementAttachCount() { mAttachCount--; }
 
-    void SetSource(const nsCString& src) {
+    void SetSource(const nsAString& src) {
         // XXX do some quick gzip here maybe -- getting this will be very rare
         mSource.Assign(src);
     }
 
-    const nsCString& Source() const { return mSource; }
+    const nsString& Source() const { return mSource; }
 
     void SetNeedsTranslation() { mNeedsTranslation = true; }
     bool NeedsTranslation() const { return mNeedsTranslation; }
 
     void SetTranslationSuccess() {
         mTranslationLog.SetIsVoid(PR_TRUE);
         mNeedsTranslation = false;
     }
 
     void SetTranslationFailure(const nsCString& msg) {
-        mTranslationLog.Assign(msg);
+        mTranslationLog.Assign(msg); 
     }
 
     const nsCString& TranslationLog() const { return mTranslationLog; }
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBGLSHADER
 protected:
     WebGLuint mName;
     PRBool mDeleted;
     WebGLenum mType;
-    nsCString mSource;
+    nsString mSource;
     nsCString mTranslationLog;
     bool mNeedsTranslation;
     PRUint32 mAttachCount;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(WebGLShader, WEBGLSHADER_PRIVATE_IID)
 
 #define WEBGLPROGRAM_PRIVATE_IID \
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -57,16 +57,17 @@
 #include "jstypedarray.h"
 
 #if defined(USE_ANGLE)
 // shader translator
 #include "angle/ShaderLang.h"
 #endif
 
 #include "WebGLTexelConversions.h"
+#include "WebGLValidateStrings.h"
 
 using namespace mozilla;
 
 static PRBool BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize);
 static WebGLenum InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2);
 
 /* Helper macros for when we're just wrapping a gl method, so that
  * we can avoid having to type this 500 times.  Note that these MUST
@@ -177,18 +178,18 @@ WebGLContext::AttachShader(nsIWebGLProgr
 
 NS_IMETHODIMP
 WebGLContext::BindAttribLocation(nsIWebGLProgram *pobj, WebGLuint location, const nsAString& name)
 {
     WebGLuint progname;
     if (!GetGLName<WebGLProgram>("bindAttribLocation: program", pobj, &progname))
         return NS_OK;
 
-    if (name.IsEmpty())
-        return ErrorInvalidValue("BindAttribLocation: name can't be null or empty");
+    if (!ValidateGLSLVariableName(name, "bindAttribLocation"))
+        return NS_OK;
 
     if (!ValidateAttribIndex(location, "bindAttribLocation"))
         return NS_OK;
 
     MakeContextCurrent();
 
     gl->fBindAttribLocation(progname, location, NS_LossyConvertUTF16toASCII(name).get());
 
@@ -1851,17 +1852,17 @@ WebGLContext::GetAttribLocation(nsIWebGL
                                 PRInt32 *retval)
 {
     *retval = 0;
 
     WebGLuint progname;
     if (!GetGLName<WebGLProgram>("getAttribLocation: program", pobj, &progname))
         return NS_OK;
 
-    if (!ValidateGLSLIdentifier(name, "getAttribLocation"))
+    if (!ValidateGLSLVariableName(name, "getAttribLocation"))
         return NS_OK; 
 
     MakeContextCurrent();
     *retval = gl->fGetAttribLocation(progname, NS_LossyConvertUTF16toASCII(name).get());
     return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -2666,17 +2667,17 @@ WebGLContext::GetUniformLocation(nsIWebG
 {
     *retval = nsnull;
 
     WebGLuint progname;
     WebGLProgram *prog;
     if (!GetConcreteObjectAndGLName("getUniformLocation: program", pobj, &prog, &progname))
         return NS_OK;
 
-    if (!ValidateGLSLIdentifier(name, "getUniformLocation"))
+    if (!ValidateGLSLVariableName(name, "getUniformLocation"))
         return NS_OK; 
 
     MakeContextCurrent();
 
     GLint intlocation = gl->fGetUniformLocation(progname, NS_LossyConvertUTF16toASCII(name).get());
 
     nsRefPtr<nsIWebGLUniformLocation> loc = prog->GetUniformLocationObject(intlocation);
     *retval = loc.forget().get();
@@ -3965,18 +3966,35 @@ WebGLContext::CompileShader(nsIWebGLShad
         resources.MaxFragmentUniformVectors = mGLMaxFragmentUniformVectors;
         resources.MaxDrawBuffers = 1;
 
         compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(),
                                        SH_WEBGL_SPEC,
                                        gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT,
                                        &resources);
 
-        nsPromiseFlatCString src(shader->Source());
-        const char *s = src.get();
+        // We're storing an actual instance of StripComments because, if we don't, the 
+        // cleanSource nsAString instance will be destroyed before the reference is
+        // actually used.
+        StripComments stripComments(shader->Source());
+        const nsAString& cleanSource = nsString(stripComments.result().Elements(), stripComments.length());
+        if (!ValidateGLSLString(cleanSource, "compileShader"))
+            return NS_OK;
+
+        const nsPromiseFlatString& flatSource = PromiseFlatString(cleanSource);
+
+        // shaderSource() already checks that the source stripped of comments is in the
+        // 7-bit ASCII range, so we can skip the NS_IsAscii() check.
+        const nsCString& sourceCString = NS_LossyConvertUTF16toASCII(flatSource);
+    
+        const PRUint32 maxSourceLength = (PRUint32(1)<<18) - 1;
+        if (sourceCString.Length() > maxSourceLength)
+            return ErrorInvalidValue("compileShader: source has more than %d characters", maxSourceLength);
+
+        const char *s = sourceCString.get();
 
         if (!ShCompile(compiler, &s, 1, SH_OBJECT_CODE)) {
             int len = 0;
             ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &len);
 
             if (len) {
                 nsCAutoString info;
                 info.SetLength(len);
@@ -4007,25 +4025,20 @@ WebGLContext::CompileShader(nsIWebGLShad
             gl->fShaderSource(shadername, 1, &ts, NULL);
         } else {
             gl->fShaderSource(shadername, 1, &s, NULL);
         }
 
         shader->SetTranslationSuccess();
 
         ShDestruct(compiler);
-    } else
+
+        gl->fCompileShader(shadername);
+    }
 #endif
-    {
-        const char *s = nsDependentCString(shader->Source()).get();
-        gl->fShaderSource(shadername, 1, &s, NULL);
-        shader->SetTranslationSuccess();
-    }
-
-    gl->fCompileShader(shadername);
 
     return NS_OK;
 }
 
 
 NS_IMETHODIMP
 WebGLContext::GetShaderParameter(nsIWebGLShader *sobj, WebGLenum pname, nsIVariant **retval)
 {
@@ -4114,41 +4127,38 @@ WebGLContext::GetShaderInfoLog(nsIWebGLS
 NS_IMETHODIMP
 WebGLContext::GetShaderSource(nsIWebGLShader *sobj, nsAString& retval)
 {
     WebGLShader *shader;
     WebGLuint shadername;
     if (!GetConcreteObjectAndGLName("getShaderSource: shader", sobj, &shader, &shadername))
         return NS_OK;
 
-    CopyASCIItoUTF16(shader->Source(), retval);
+    retval.Assign(shader->Source());
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::ShaderSource(nsIWebGLShader *sobj, const nsAString& source)
 {
     WebGLShader *shader;
     WebGLuint shadername;
     if (!GetConcreteObjectAndGLName("shaderSource: shader", sobj, &shader, &shadername))
         return NS_OK;
-    
-    const nsPromiseFlatString& flatSource = PromiseFlatString(source);
-
-    if (!NS_IsAscii(flatSource.get()))
-        return ErrorInvalidValue("shaderSource: non-ascii characters found in source");
-
-    const nsCString& sourceCString = NS_LossyConvertUTF16toASCII(flatSource);
-    
-    const PRUint32 maxSourceLength = (PRUint32(1)<<18) - 1;
-    if (sourceCString.Length() > maxSourceLength)
-        return ErrorInvalidValue("shaderSource: source has more than %d characters", maxSourceLength);
-    
-    shader->SetSource(sourceCString);
+
+    // We're storing an actual instance of StripComments because, if we don't, the 
+    // cleanSource nsAString instance will be destroyed before the reference is
+    // actually used.
+    StripComments stripComments(source);
+    const nsAString& cleanSource = nsString(stripComments.result().Elements(), stripComments.length());
+    if (!ValidateGLSLString(cleanSource, "compileShader"))
+        return NS_OK;
+
+    shader->SetSource(source);
 
     shader->SetNeedsTranslation();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type,
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -323,24 +323,41 @@ PRBool WebGLContext::ValidateDrawModeEnu
         case LOCAL_GL_LINES:
             return PR_TRUE;
         default:
             ErrorInvalidEnumInfo(info, mode);
             return PR_FALSE;
     }
 }
 
-bool WebGLContext::ValidateGLSLIdentifier(const nsAString& name, const char *info)
+bool WebGLContext::ValidateGLSLVariableName(const nsAString& name, const char *info)
 {
-    const PRUint32 maxSize = 4095;
+    const PRUint32 maxSize = 255;
     if (name.Length() > maxSize) {
         ErrorInvalidValue("%s: identifier is %d characters long, exceeds the maximum allowed length of %d characters",
                           info, name.Length(), maxSize);
         return false;
     }
+
+    if (!ValidateGLSLString(name, info)) {
+        return false;
+    }
+
+    return true;
+}
+
+bool WebGLContext::ValidateGLSLString(const nsAString& string, const char *info)
+{
+    for (PRUint32 i = 0; i < string.Length(); ++i) {
+        if (!ValidateGLSLCharacter(string.CharAt(i))) {
+             ErrorInvalidValue("%s: string contains the illegal character '%d'", info, string.CharAt(i));
+             return false;
+        }
+    }
+
     return true;
 }
 
 PRUint32 WebGLContext::GetTexelSize(WebGLenum format, WebGLenum type)
 {
     if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
         int multiplier = type == LOCAL_GL_FLOAT ? 4 : 1;
         switch (format) {
new file mode 100644
--- /dev/null
+++ b/content/canvas/src/WebGLValidateStrings.h
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Mozilla Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WEBGLVALIDATESTRINGS_H_
+#define WEBGLVALIDATESTRINGS_H_
+
+#include "WebGLContext.h"
+
+namespace mozilla {
+
+// The following code was taken from the WebKit WebGL implementation,
+// which can be found here:
+// http://trac.webkit.org/browser/trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp?rev=93625#L121
+// Note that some modifications were done to adapt it to Mozilla.
+/****** BEGIN CODE TAKEN FROM WEBKIT ******/
+    bool WebGLContext::ValidateGLSLCharacter(PRUnichar 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;
+    }
+
+    // Strips comments from shader text. This allows non-ASCII characters
+    // to be used in comments without potentially breaking OpenGL
+    // implementations not expecting characters outside the GLSL ES set.
+    class StripComments {
+    public:
+        StripComments(const nsAString& str)
+            : m_parseState(BeginningOfLine)
+            , m_end(str.EndReading())
+            , m_current(str.BeginReading())
+            , m_position(0)
+        {
+            m_result.SetLength(str.Length());
+            parse();
+        }
+
+        const nsTArray<PRUnichar>& result()
+        {
+            return m_result;
+        }
+
+        size_t length()
+        {
+            return m_position;
+        }
+
+    private:
+        bool hasMoreCharacters()
+        {
+            return (m_current < m_end);
+        }
+
+        void parse()
+        {
+            while (hasMoreCharacters()) {
+                process(current());
+                // process() might advance the position.
+                if (hasMoreCharacters())
+                    advance();
+            }
+        }
+
+        void process(PRUnichar);
+
+        bool peek(PRUnichar& character)
+        {
+            if (m_current + 1 >= m_end)
+                return false;
+            character = *(m_current + 1);
+            return true;
+        }
+
+        PRUnichar current()
+        {
+            //ASSERT(m_position < m_length);
+            return *m_current;
+        }
+
+        void advance()
+        {
+            ++m_current;
+        }
+
+        bool isNewline(PRUnichar character)
+        {
+            // Don't attempt to canonicalize newline related characters.
+            return (character == '\n' || character == '\r');
+        }
+
+        void emit(PRUnichar character)
+        {
+            m_result[m_position++] = character;
+        }
+
+        enum ParseState {
+            // Have not seen an ASCII non-whitespace character yet on
+            // this line. Possible that we might see a preprocessor
+            // directive.
+            BeginningOfLine,
+
+            // Have seen at least one ASCII non-whitespace character
+            // on this line.
+            MiddleOfLine,
+
+            // Handling a preprocessor directive. Passes through all
+            // characters up to the end of the line. Disables comment
+            // processing.
+            InPreprocessorDirective,
+
+            // Handling a single-line comment. The comment text is
+            // replaced with a single space.
+            InSingleLineComment,
+
+            // Handling a multi-line comment. Newlines are passed
+            // through to preserve line numbers.
+            InMultiLineComment
+        };
+
+        ParseState m_parseState;
+        const PRUnichar* m_end;
+        const PRUnichar* m_current;
+        size_t m_position;
+        nsTArray<PRUnichar> m_result;
+    };
+
+    void StripComments::process(PRUnichar c)
+    {
+        if (isNewline(c)) {
+            // No matter what state we are in, pass through newlines
+            // so we preserve line numbers.
+            emit(c);
+
+            if (m_parseState != InMultiLineComment)
+                m_parseState = BeginningOfLine;
+
+            return;
+        }
+
+        PRUnichar temp = 0;
+        switch (m_parseState) {
+        case BeginningOfLine:
+            // If it's an ASCII space.
+            if (c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9))) {
+                emit(c);
+                break;
+            }
+
+            if (c == '#') {
+                m_parseState = InPreprocessorDirective;
+                emit(c);
+                break;
+            }
+
+            // Transition to normal state and re-handle character.
+            m_parseState = MiddleOfLine;
+            process(c);
+            break;
+
+        case MiddleOfLine:
+            if (c == '/' && peek(temp)) {
+                if (temp == '/') {
+                    m_parseState = InSingleLineComment;
+                    emit(' ');
+                    advance();
+                    break;
+                }
+
+                if (temp == '*') {
+                    m_parseState = InMultiLineComment;
+                    // Emit the comment start in case the user has
+                    // an unclosed comment and we want to later
+                    // signal an error.
+                    emit('/');
+                    emit('*');
+                    advance();
+                    break;
+                }
+            }
+
+            emit(c);
+            break;
+
+        case InPreprocessorDirective:
+            // No matter what the character is, just pass it
+            // through. Do not parse comments in this state. This
+            // might not be the right thing to do long term, but it
+            // should handle the #error preprocessor directive.
+            emit(c);
+            break;
+
+        case InSingleLineComment:
+            // The newline code at the top of this function takes care
+            // of resetting our state when we get out of the
+            // single-line comment. Swallow all other characters.
+            break;
+
+        case InMultiLineComment:
+            if (c == '*' && peek(temp) && temp == '/') {
+                emit('*');
+                emit('/');
+                m_parseState = MiddleOfLine;
+                advance();
+                break;
+            }
+
+            // Swallow all other characters. Unclear whether we may
+            // want or need to just emit a space per character to try
+            // to preserve column numbers for debugging purposes.
+            break;
+        }
+    }
+
+/****** END CODE TAKEN FROM WEBKIT ******/
+
+} // end namespace mozilla
+
+#endif // WEBGLVALIDATESTRINGS_H_
--- a/content/canvas/test/webgl/failing_tests_linux.txt
+++ b/content/canvas/test/webgl/failing_tests_linux.txt
@@ -3,21 +3,19 @@ conformance/drawingbuffer-test.html
 conformance/framebuffer-object-attachment.html
 conformance/shaders/glsl-features/../../glsl-features.html?feature=abs-frag&reffs=shaders/glsl-features/abs-ref.frag&testfs=shaders/glsl-features/abs.frag
 conformance/shaders/glsl-features/../../glsl-features.html?feature=abs-vert-vec2&refvs=shaders/glsl-features/abs-vec2-ref.vert&testvs=shaders/glsl-features/abs-vec2.vert
 conformance/shaders/glsl-features/../../glsl-features.html?feature=abs-vert-vec3&refvs=shaders/glsl-features/abs-vec3-ref.vert&testvs=shaders/glsl-features/abs-vec3.vert
 conformance/shaders/glsl-features/../../glsl-features.html?feature=abs-vert-vec4&refvs=shaders/glsl-features/abs-vec4-ref.vert&testvs=shaders/glsl-features/abs-vec4.vert
 conformance/shaders/glsl-features/../../glsl-features.html?feature=sign-frag-vec4&reffs=shaders/glsl-features/sign-vec4-ref.frag&testfs=shaders/glsl-features/sign-vec4.frag
 conformance/shaders/glsl-features/../../glsl-features.html?feature=sign-vert-vec4&refvs=shaders/glsl-features/sign-vec4-ref.vert&testvs=shaders/glsl-features/sign-vec4.vert
 conformance/gl-get-active-attribute.html
-conformance/gl-getshadersource.html
 conformance/gl-uniform-bool.html
 conformance/glsl-conformance.html
 conformance/glsl-long-variable-names.html
-conformance/invalid-passed-params.html
 conformance/premultiplyalpha-test.html
 conformance/read-pixels-test.html
 conformance/uninitialized-test.html
 conformance/more/conformance/quickCheckAPI.html
 conformance/more/functions/copyTexImage2D.html
 conformance/more/functions/copyTexSubImage2D.html
 conformance/more/functions/deleteBufferBadArgs.html
 conformance/more/functions/uniformfArrayLen1.html
--- a/content/canvas/test/webgl/failing_tests_mac.txt
+++ b/content/canvas/test/webgl/failing_tests_mac.txt
@@ -1,17 +1,15 @@
 conformance/context-attributes-alpha-depth-stencil-antialias.html
 conformance/drawingbuffer-static-canvas-test.html
 conformance/drawingbuffer-test.html
 conformance/framebuffer-object-attachment.html
-conformance/gl-getshadersource.html
 conformance/gl-object-get-calls.html
 conformance/glsl-conformance.html
 conformance/glsl-long-variable-names.html
-conformance/invalid-passed-params.html
 conformance/premultiplyalpha-test.html
 conformance/program-test.html
 conformance/read-pixels-test.html
 conformance/tex-input-validation.html
 conformance/texture-npot.html
 conformance/more/conformance/quickCheckAPI.html
 conformance/more/functions/copyTexImage2D.html
 conformance/more/functions/copyTexSubImage2D.html
--- a/content/canvas/test/webgl/failing_tests_windows.txt
+++ b/content/canvas/test/webgl/failing_tests_windows.txt
@@ -1,14 +1,12 @@
 conformance/drawingbuffer-static-canvas-test.html
 conformance/drawingbuffer-test.html
 conformance/framebuffer-object-attachment.html
-conformance/gl-getshadersource.html
 conformance/glsl-conformance.html
 conformance/glsl-long-variable-names.html
-conformance/invalid-passed-params.html
 conformance/premultiplyalpha-test.html
 conformance/read-pixels-test.html
 conformance/more/conformance/quickCheckAPI.html
 conformance/more/functions/copyTexImage2D.html
 conformance/more/functions/copyTexSubImage2D.html
 conformance/more/functions/deleteBufferBadArgs.html
 conformance/more/functions/uniformfArrayLen1.html