tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestFeaturePolicyParser.cpp (6820B)


      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 file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "gtest/gtest.h"
      8 #include "mozilla/BasePrincipal.h"
      9 #include "mozilla/dom/Feature.h"
     10 #include "mozilla/dom/FeaturePolicyParser.h"
     11 #include "nsNetUtil.h"
     12 #include "nsTArray.h"
     13 
     14 using namespace mozilla;
     15 using namespace mozilla::dom;
     16 
     17 #define URL_SELF "https://example.com"_ns
     18 #define URL_EXAMPLE_COM "http://example.com"_ns
     19 #define URL_EXAMPLE_NET "http://example.net"_ns
     20 
     21 void CheckParser(const nsAString& aInput, bool aExpectedResults,
     22                 uint32_t aExpectedFeatures,
     23                 nsTArray<Feature>& aParsedFeatures) {
     24  nsCOMPtr<nsIPrincipal> principal =
     25      mozilla::BasePrincipal::CreateContentPrincipal(URL_SELF);
     26  nsTArray<Feature> parsedFeatures;
     27  ASSERT_TRUE(FeaturePolicyParser::ParseString(aInput, nullptr, principal,
     28                                               principal, parsedFeatures) ==
     29              aExpectedResults);
     30  ASSERT_TRUE(parsedFeatures.Length() == aExpectedFeatures);
     31 
     32  aParsedFeatures = std::move(parsedFeatures);
     33 }
     34 
     35 TEST(FeaturePolicyParser, Basic)
     36 {
     37  nsCOMPtr<nsIPrincipal> selfPrincipal =
     38      mozilla::BasePrincipal::CreateContentPrincipal(URL_SELF);
     39  nsCOMPtr<nsIPrincipal> exampleComPrincipal =
     40      mozilla::BasePrincipal::CreateContentPrincipal(URL_EXAMPLE_COM);
     41  nsCOMPtr<nsIPrincipal> exampleNetPrincipal =
     42      mozilla::BasePrincipal::CreateContentPrincipal(URL_EXAMPLE_NET);
     43 
     44  nsTArray<Feature> parsedFeatures;
     45 
     46  // Empty string is a valid policy.
     47  CheckParser(u""_ns, true, 0, parsedFeatures);
     48 
     49  // Empty string with spaces is still valid.
     50  CheckParser(u"   "_ns, true, 0, parsedFeatures);
     51 
     52  // Non-Existing features with no allowed values
     53  CheckParser(u"non-existing-feature"_ns, true, 0, parsedFeatures);
     54  CheckParser(u"non-existing-feature;another-feature"_ns, true, 0,
     55              parsedFeatures);
     56 
     57  // Existing feature with no allowed values
     58  CheckParser(u"camera"_ns, true, 1, parsedFeatures);
     59  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
     60  ASSERT_TRUE(parsedFeatures[0].HasAllowList());
     61 
     62  // Some spaces.
     63  CheckParser(u" camera "_ns, true, 1, parsedFeatures);
     64  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
     65  ASSERT_TRUE(parsedFeatures[0].HasAllowList());
     66 
     67  // A random ;
     68  CheckParser(u"camera;"_ns, true, 1, parsedFeatures);
     69  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
     70  ASSERT_TRUE(parsedFeatures[0].HasAllowList());
     71 
     72  // Another random ;
     73  CheckParser(u";camera;"_ns, true, 1, parsedFeatures);
     74  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
     75  ASSERT_TRUE(parsedFeatures[0].HasAllowList());
     76 
     77  // 2 features
     78  CheckParser(u"camera;microphone"_ns, true, 2, parsedFeatures);
     79  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
     80  ASSERT_TRUE(parsedFeatures[0].HasAllowList());
     81  ASSERT_TRUE(parsedFeatures[1].Name().Equals(u"microphone"_ns));
     82  ASSERT_TRUE(parsedFeatures[1].HasAllowList());
     83 
     84  // 2 features with spaces
     85  CheckParser(u" camera ; microphone "_ns, true, 2, parsedFeatures);
     86  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
     87  ASSERT_TRUE(parsedFeatures[0].HasAllowList());
     88  ASSERT_TRUE(parsedFeatures[1].Name().Equals(u"microphone"_ns));
     89  ASSERT_TRUE(parsedFeatures[1].HasAllowList());
     90 
     91  // 3 features, but only 2 exist.
     92  CheckParser(u"camera;microphone;foobar"_ns, true, 2, parsedFeatures);
     93  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
     94  ASSERT_TRUE(parsedFeatures[0].HasAllowList());
     95  ASSERT_TRUE(parsedFeatures[1].Name().Equals(u"microphone"_ns));
     96  ASSERT_TRUE(parsedFeatures[1].HasAllowList());
     97 
     98  // Multiple spaces around the value
     99  CheckParser(u"camera      'self'"_ns, true, 1, parsedFeatures);
    100  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    101  ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
    102 
    103  // Multiple spaces around the value
    104  CheckParser(u"camera      'self'    "_ns, true, 1, parsedFeatures);
    105  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    106  ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
    107 
    108  // No final '
    109  CheckParser(u"camera      'self"_ns, true, 1, parsedFeatures);
    110  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    111  ASSERT_TRUE(parsedFeatures[0].HasAllowList());
    112  ASSERT_TRUE(!parsedFeatures[0].AllowListContains(selfPrincipal));
    113 
    114  // Lowercase/Uppercase
    115  CheckParser(u"camera      'selF'"_ns, true, 1, parsedFeatures);
    116  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    117  ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
    118 
    119  // Lowercase/Uppercase
    120  CheckParser(u"camera * 'self' none' a.com 123"_ns, true, 1, parsedFeatures);
    121  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    122  ASSERT_TRUE(parsedFeatures[0].AllowsAll());
    123 
    124  // After a 'none' we don't continue the parsing.
    125  CheckParser(u"camera 'none' a.com b.org c.net d.co.uk"_ns, true, 1,
    126              parsedFeatures);
    127  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    128  ASSERT_TRUE(parsedFeatures[0].AllowsNone());
    129 
    130  // After a * we don't continue the parsing.
    131  CheckParser(u"camera * a.com b.org c.net d.co.uk"_ns, true, 1,
    132              parsedFeatures);
    133  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    134  ASSERT_TRUE(parsedFeatures[0].AllowsAll());
    135 
    136  // 'self'
    137  CheckParser(u"camera 'self'"_ns, true, 1, parsedFeatures);
    138  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    139  ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
    140 
    141  // A couple of URLs
    142  CheckParser(u"camera http://example.com http://example.net"_ns, true, 1,
    143              parsedFeatures);
    144  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    145  ASSERT_TRUE(!parsedFeatures[0].AllowListContains(selfPrincipal));
    146  ASSERT_TRUE(parsedFeatures[0].AllowListContains(exampleComPrincipal));
    147  ASSERT_TRUE(parsedFeatures[0].AllowListContains(exampleNetPrincipal));
    148 
    149  // A couple of URLs + self
    150  CheckParser(u"camera http://example.com 'self' http://example.net"_ns, true,
    151              1, parsedFeatures);
    152  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    153  ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
    154  ASSERT_TRUE(parsedFeatures[0].AllowListContains(exampleComPrincipal));
    155  ASSERT_TRUE(parsedFeatures[0].AllowListContains(exampleNetPrincipal));
    156 
    157  // A couple of URLs but then *
    158  CheckParser(u"camera http://example.com 'self' http://example.net *"_ns, true,
    159              1, parsedFeatures);
    160  ASSERT_TRUE(parsedFeatures[0].Name().Equals(u"camera"_ns));
    161  ASSERT_TRUE(parsedFeatures[0].AllowsAll());
    162 }