Bug 1325995 - Do our own GLSL char validity checks based on ESSL3 rules. - r=daoshengmu
MozReview-Commit-ID: 60mJqYFTQBA
--- a/dom/canvas/WebGLShader.cpp
+++ b/dom/canvas/WebGLShader.cpp
@@ -161,17 +161,17 @@ WebGLShader::ShaderSource(const nsAStrin
const char funcName[] = "shaderSource";
nsString sourceWithoutComments;
if (!TruncateComments(source, &sourceWithoutComments)) {
mContext->ErrorOutOfMemory("%s: Failed to alloc for empting comment contents.",
funcName);
return;
}
- if (!ValidateGLSLString(sourceWithoutComments, mContext, funcName))
+ if (!ValidateGLSLPreprocString(mContext, funcName, sourceWithoutComments))
return;
// We checked that the source stripped of comments is in the
// 7-bit ASCII range, so we can skip the NS_IsAscii() check.
const NS_LossyConvertUTF16toASCII cleanSource(sourceWithoutComments);
if (mContext->gl->WorkAroundDriverBugs()) {
const size_t maxSourceLength = 0x3ffff;
--- a/dom/canvas/WebGLValidateStrings.cpp
+++ b/dom/canvas/WebGLValidateStrings.cpp
@@ -1,42 +1,18 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLValidateStrings.h"
-#include "nsString.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 IsValidGLSLCharacter(char16_t 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;
-}
-/****** END CODE TAKEN FROM WEBKIT ******/
bool
TruncateComments(const nsAString& src, nsAString* const out)
{
const size_t dstByteCount = src.Length() * sizeof(src[0]);
const UniqueBuffer dst(malloc(dstByteCount));
if (!dst)
return false;
@@ -120,46 +96,123 @@ TruncateComments(const nsAString& src, n
MOZ_ASSERT((dstBegin+1) - dstBegin == 1);
const uint32_t dstCharLen = dstItr - dstBegin;
if (!out->Assign(dstBegin, dstCharLen, mozilla::fallible))
return false;
return true;
}
+////////////////////////////////////////////////////////////////////////////////
+
+static bool
+IsValidGLSLChar(char16_t c)
+{
+ if (('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') ||
+ ('0' <= c && c <= '9'))
+ {
+ return true;
+ }
+
+ switch (c) {
+ case ' ':
+ case '\t':
+ case '\v':
+ case '\f':
+ case '\r':
+ case '\n':
+ case '_':
+ case '.':
+ case '+':
+ case '-':
+ case '/':
+ case '*':
+ case '%':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '(':
+ case ')':
+ case '{':
+ case '}':
+ case '^':
+ case '|':
+ case '&':
+ case '~':
+ case '=':
+ case '!':
+ case ':':
+ case ';':
+ case ',':
+ case '?':
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static bool
+IsValidGLSLPreprocChar(char16_t c)
+{
+ if (IsValidGLSLChar(c))
+ return true;
+
+ switch (c) {
+ case '\\':
+ case '#':
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+////
+
bool
-ValidateGLSLString(const nsAString& string, WebGLContext* webgl, const char* funcName)
+ValidateGLSLPreprocString(WebGLContext* webgl, const char* funcName,
+ const nsAString& string)
{
for (size_t i = 0; i < string.Length(); ++i) {
- if (!IsValidGLSLCharacter(string.CharAt(i))) {
- webgl->ErrorInvalidValue("%s: String contains the illegal character '%d'",
- funcName, string.CharAt(i));
+ const auto& cur = string[i];
+ if (!IsValidGLSLPreprocChar(cur)) {
+ webgl->ErrorInvalidValue("%s: String contains the illegal character 0x%x.",
+ funcName, cur);
return false;
}
}
return true;
}
bool
ValidateGLSLVariableName(const nsAString& name, WebGLContext* webgl, const char* funcName)
{
if (name.IsEmpty())
return false;
const uint32_t maxSize = webgl->IsWebGL2() ? 1024 : 256;
if (name.Length() > maxSize) {
- webgl->ErrorInvalidValue("%s: Identifier is %d characters long, exceeds the"
- " maximum allowed length of %d characters.",
+ webgl->ErrorInvalidValue("%s: Identifier is %u characters long, exceeds the"
+ " maximum allowed length of %u characters.",
funcName, name.Length(), maxSize);
return false;
}
- if (!ValidateGLSLString(name, webgl, funcName))
- return false;
+ for (size_t i = 0; i < name.Length(); ++i) {
+ const auto& cur = name[i];
+ if (!IsValidGLSLChar(cur)) {
+ webgl->ErrorInvalidValue("%s: String contains the illegal character 0x%x'.",
+ funcName, cur);
+ return false;
+ }
+ }
nsString prefix1 = NS_LITERAL_STRING("webgl_");
nsString prefix2 = NS_LITERAL_STRING("_webgl_");
if (Substring(name, 0, prefix1.Length()).Equals(prefix1) ||
Substring(name, 0, prefix2.Length()).Equals(prefix2))
{
webgl->ErrorInvalidOperation("%s: String contains a reserved GLSL prefix.",
--- a/dom/canvas/WebGLValidateStrings.h
+++ b/dom/canvas/WebGLValidateStrings.h
@@ -23,26 +23,25 @@
* (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 WEBGL_VALIDATE_STRINGS_H_
#define WEBGL_VALIDATE_STRINGS_H_
#include "nsString.h"
-#include "nsTArray.h"
namespace mozilla {
class WebGLContext;
bool
TruncateComments(const nsAString& src, nsAString* const out);
-
-bool ValidateGLSLString(const nsAString& string, WebGLContext* webgl,
- const char* funcName);
-
-bool ValidateGLSLVariableName(const nsAString& name, WebGLContext* webgl,
- const char* funcName);
+bool
+ValidateGLSLPreprocString(WebGLContext* webgl, const char* funcName,
+ const nsAString& string);
+bool
+ValidateGLSLVariableName(const nsAString& name, WebGLContext* webgl,
+ const char* funcName);
} // namespace mozilla
#endif // WEBGL_VALIDATE_STRINGS_H_