LCOV - code coverage report
Current view: top level - dom/canvas - WebGLValidateStrings.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 105 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "WebGLValidateStrings.h"
       7             : 
       8             : #include "WebGLContext.h"
       9             : 
      10             : namespace mozilla {
      11             : 
      12             : bool
      13           0 : TruncateComments(const nsAString& src, nsAString* const out)
      14             : {
      15           0 :     const size_t dstByteCount = src.Length() * sizeof(src[0]);
      16           0 :     const UniqueBuffer dst(malloc(dstByteCount));
      17           0 :     if (!dst)
      18           0 :         return false;
      19             : 
      20           0 :     auto srcItr = src.BeginReading();
      21           0 :     const auto srcEnd = src.EndReading();
      22           0 :     const auto dstBegin = (decltype(src[0])*)dst.get();
      23           0 :     auto dstItr = dstBegin;
      24             : 
      25           0 :     const auto fnEmitUntil = [&](const decltype(srcItr)& nextSrcItr) {
      26           0 :         while (srcItr != nextSrcItr) {
      27           0 :             *dstItr = *srcItr;
      28           0 :             ++srcItr;
      29           0 :             ++dstItr;
      30             :         }
      31           0 :     };
      32             : 
      33             :     const auto fnFindSoonestOf = [&](const nsString* needles, size_t needleCount,
      34           0 :                                      size_t* const out_foundId)
      35             :     {
      36           0 :         auto foundItr = srcItr;
      37           0 :         while (foundItr != srcEnd) {
      38           0 :             const auto haystack = Substring(foundItr, srcEnd);
      39           0 :             for (size_t i = 0; i < needleCount; i++) {
      40           0 :                 if (StringBeginsWith(haystack, needles[i])) {
      41           0 :                     *out_foundId = i;
      42           0 :                     return foundItr;
      43             :                 }
      44             :             }
      45           0 :             ++foundItr;
      46             :         }
      47           0 :         *out_foundId = needleCount;
      48           0 :         return foundItr;
      49           0 :     };
      50             : 
      51             :     ////
      52             : 
      53           0 :     const nsString commentBeginnings[] = { NS_LITERAL_STRING("//"),
      54           0 :                                            NS_LITERAL_STRING("/*"),
      55           0 :                                            nsString() }; // Final empty string for "found
      56             :                                                          // nothing".
      57           0 :     const nsString lineCommentEndings[] = { NS_LITERAL_STRING("\\\n"),
      58           0 :                                             NS_LITERAL_STRING("\n"),
      59           0 :                                             nsString() };
      60           0 :     const nsString blockCommentEndings[] = { NS_LITERAL_STRING("\n"),
      61           0 :                                              NS_LITERAL_STRING("*/"),
      62           0 :                                              nsString() };
      63             : 
      64           0 :     while (srcItr != srcEnd) {
      65             :         size_t foundId;
      66           0 :         fnEmitUntil( fnFindSoonestOf(commentBeginnings, 2, &foundId) );
      67           0 :         fnEmitUntil(srcItr + commentBeginnings[foundId].Length()); // Final empty string
      68             :                                                                    // allows us to skip
      69             :                                                                    // forward here
      70             :                                                                    // unconditionally.
      71           0 :         switch (foundId) {
      72             :         case 0: // line comment
      73             :             while (true) {
      74             :                 size_t endId;
      75           0 :                 srcItr = fnFindSoonestOf(lineCommentEndings, 2, &endId);
      76           0 :                 fnEmitUntil(srcItr + lineCommentEndings[endId].Length());
      77           0 :                 if (endId == 0)
      78           0 :                     continue;
      79           0 :                 break;
      80           0 :             }
      81           0 :             break;
      82             : 
      83             :         case 1: // block comment
      84             :             while (true) {
      85             :                 size_t endId;
      86           0 :                 srcItr = fnFindSoonestOf(blockCommentEndings, 2, &endId);
      87           0 :                 fnEmitUntil(srcItr + blockCommentEndings[endId].Length());
      88           0 :                 if (endId == 0)
      89           0 :                     continue;
      90           0 :                 break;
      91           0 :             }
      92           0 :             break;
      93             : 
      94             :         default: // not found
      95           0 :             break;
      96             :         }
      97             :     }
      98             : 
      99             :     MOZ_ASSERT((dstBegin+1) - dstBegin == 1);
     100           0 :     const uint32_t dstCharLen = dstItr - dstBegin;
     101           0 :     if (!out->Assign(dstBegin, dstCharLen, mozilla::fallible))
     102           0 :         return false;
     103             : 
     104           0 :     return true;
     105             : }
     106             : 
     107             : ////////////////////////////////////////////////////////////////////////////////
     108             : 
     109             : static bool
     110           0 : IsValidGLSLChar(char16_t c)
     111             : {
     112           0 :     if (('a' <= c && c <= 'z') ||
     113           0 :         ('A' <= c && c <= 'Z') ||
     114           0 :         ('0' <= c && c <= '9'))
     115             :     {
     116           0 :         return true;
     117             :     }
     118             : 
     119           0 :     switch (c) {
     120             :     case ' ':
     121             :     case '\t':
     122             :     case '\v':
     123             :     case '\f':
     124             :     case '\r':
     125             :     case '\n':
     126             :     case '_':
     127             :     case '.':
     128             :     case '+':
     129             :     case '-':
     130             :     case '/':
     131             :     case '*':
     132             :     case '%':
     133             :     case '<':
     134             :     case '>':
     135             :     case '[':
     136             :     case ']':
     137             :     case '(':
     138             :     case ')':
     139             :     case '{':
     140             :     case '}':
     141             :     case '^':
     142             :     case '|':
     143             :     case '&':
     144             :     case '~':
     145             :     case '=':
     146             :     case '!':
     147             :     case ':':
     148             :     case ';':
     149             :     case ',':
     150             :     case '?':
     151           0 :         return true;
     152             : 
     153             :     default:
     154           0 :         return false;
     155             :     }
     156             : }
     157             : 
     158             : static bool
     159           0 : IsValidGLSLPreprocChar(char16_t c)
     160             : {
     161           0 :     if (IsValidGLSLChar(c))
     162           0 :         return true;
     163             : 
     164           0 :     switch (c) {
     165             :     case '\\':
     166             :     case '#':
     167           0 :         return true;
     168             : 
     169             :     default:
     170           0 :         return false;
     171             :     }
     172             : }
     173             : 
     174             : ////
     175             : 
     176             : bool
     177           0 : ValidateGLSLPreprocString(WebGLContext* webgl, const char* funcName,
     178             :                           const nsAString& string)
     179             : {
     180           0 :     for (size_t i = 0; i < string.Length(); ++i) {
     181           0 :         const auto& cur = string[i];
     182             : 
     183           0 :         if (!IsValidGLSLPreprocChar(cur)) {
     184           0 :             webgl->ErrorInvalidValue("%s: String contains the illegal character 0x%x.",
     185           0 :                                      funcName, cur);
     186           0 :             return false;
     187             :         }
     188             : 
     189           0 :         if (cur == '\\' && !webgl->IsWebGL2()) {
     190             :             // Todo: Backslash is technically still invalid in WebGLSL 1 under even under
     191             :             // WebGL 2.
     192           0 :             webgl->ErrorInvalidValue("%s: Backslash is not valid in WebGL 1.", funcName);
     193           0 :             return false;
     194             :         }
     195             :     }
     196             : 
     197           0 :     return true;
     198             : }
     199             : 
     200             : bool
     201           0 : ValidateGLSLVariableName(const nsAString& name, WebGLContext* webgl, const char* funcName)
     202             : {
     203           0 :     if (name.IsEmpty())
     204           0 :         return false;
     205             : 
     206           0 :     const uint32_t maxSize = webgl->IsWebGL2() ? 1024 : 256;
     207           0 :     if (name.Length() > maxSize) {
     208           0 :         webgl->ErrorInvalidValue("%s: Identifier is %u characters long, exceeds the"
     209             :                                  " maximum allowed length of %u characters.",
     210           0 :                                  funcName, name.Length(), maxSize);
     211           0 :         return false;
     212             :     }
     213             : 
     214           0 :     for (size_t i = 0; i < name.Length(); ++i) {
     215           0 :         const auto& cur = name[i];
     216           0 :         if (!IsValidGLSLChar(cur)) {
     217           0 :            webgl->ErrorInvalidValue("%s: String contains the illegal character 0x%x'.",
     218           0 :                                     funcName, cur);
     219           0 :            return false;
     220             :         }
     221             :     }
     222             : 
     223           0 :     nsString prefix1 = NS_LITERAL_STRING("webgl_");
     224           0 :     nsString prefix2 = NS_LITERAL_STRING("_webgl_");
     225             : 
     226           0 :     if (Substring(name, 0, prefix1.Length()).Equals(prefix1) ||
     227           0 :         Substring(name, 0, prefix2.Length()).Equals(prefix2))
     228             :     {
     229             :         webgl->ErrorInvalidOperation("%s: String contains a reserved GLSL prefix.",
     230           0 :                                      funcName);
     231           0 :         return false;
     232             :     }
     233             : 
     234           0 :     return true;
     235             : }
     236             : 
     237             : } // namespace mozilla

Generated by: LCOV version 1.13