1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef PolicyTokenizer_h___
8 #define PolicyTokenizer_h___
9 
10 #include "nsContentUtils.h"
11 #include "nsString.h"
12 
13 /**
14  * How does the parsing work?
15  *
16  * We generate tokens by splitting the policy-string by whitespace and
17  * semicolon. Interally the tokens are represented as an array of string-arrays:
18  *
19  *  [
20  *    [ name, src, src, src, ... ],
21  *    [ name, src, src, src, ... ],
22  *    [ name, src, src, src, ... ]
23  *  ]
24  *
25  * for example:
26  *  [
27  *    [ img-src, http://www.example.com, http:www.test.com ],
28  *    [ default-src, 'self'],
29  *    [ script-src, 'unsafe-eval', 'unsafe-inline' ],
30  *  ]
31  */
32 
33 typedef nsTArray<CopyableTArray<nsString> > policyTokens;
34 
35 class PolicyTokenizer {
36  public:
37   static void tokenizePolicy(const nsAString& aPolicyString,
38                              policyTokens& outTokens);
39 
40  private:
41   PolicyTokenizer(const char16_t* aStart, const char16_t* aEnd);
42   ~PolicyTokenizer();
43 
atEnd()44   inline bool atEnd() { return mCurChar >= mEndChar; }
45 
skipWhiteSpace()46   inline void skipWhiteSpace() {
47     while (mCurChar < mEndChar && nsContentUtils::IsHTMLWhitespace(*mCurChar)) {
48       mCurChar++;
49     }
50     mCurToken.Truncate();
51   }
52 
skipWhiteSpaceAndSemicolon()53   inline void skipWhiteSpaceAndSemicolon() {
54     while (mCurChar < mEndChar &&
55            (*mCurChar == ';' || nsContentUtils::IsHTMLWhitespace(*mCurChar))) {
56       mCurChar++;
57     }
58     mCurToken.Truncate();
59   }
60 
accept(char16_t aChar)61   inline bool accept(char16_t aChar) {
62     NS_ASSERTION(mCurChar < mEndChar, "Trying to dereference mEndChar");
63     if (*mCurChar == aChar) {
64       mCurToken.Append(*mCurChar++);
65       return true;
66     }
67     return false;
68   }
69 
70   void generateNextToken();
71   void generateTokens(policyTokens& outTokens);
72 
73   const char16_t* mCurChar;
74   const char16_t* mEndChar;
75   nsString mCurToken;
76 };
77 
78 #endif /* PolicyTokenizer_h___ */
79