Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/dom/InternalHeaders.h
Line
Count
Source (jump to first uncovered line)
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 mozilla_dom_InternalHeaders_h
8
#define mozilla_dom_InternalHeaders_h
9
10
// needed for HeadersGuardEnum.
11
#include "mozilla/dom/HeadersBinding.h"
12
#include "mozilla/dom/UnionTypes.h"
13
14
#include "nsClassHashtable.h"
15
#include "nsWrapperCache.h"
16
17
namespace mozilla {
18
19
class ErrorResult;
20
21
namespace dom {
22
23
template<typename K, typename V> class Record;
24
class HeadersEntry;
25
26
class InternalHeaders final
27
{
28
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalHeaders)
29
30
public:
31
  struct Entry
32
  {
33
    Entry(const nsACString& aName, const nsACString& aValue)
34
      : mName(aName)
35
      , mValue(aValue)
36
0
    { }
37
38
0
    Entry() { }
39
40
    nsCString mName;
41
    nsCString mValue;
42
  };
43
44
private:
45
  HeadersGuardEnum mGuard;
46
  nsTArray<Entry> mList;
47
48
  nsTArray<Entry> mSortedList;
49
50
  // This boolean is set to true at any writing operation to mList. It's set to
51
  // false when mSortedList is regenerated. This happens when the header is
52
  // iterated.
53
  bool mListDirty;
54
55
public:
56
  explicit InternalHeaders(HeadersGuardEnum aGuard = HeadersGuardEnum::None)
57
    : mGuard(aGuard)
58
    , mListDirty(false)
59
0
  {
60
0
  }
61
62
  explicit InternalHeaders(const InternalHeaders& aOther)
63
    : mGuard(HeadersGuardEnum::None)
64
    , mListDirty(true)
65
0
  {
66
0
    ErrorResult result;
67
0
    Fill(aOther, result);
68
0
    MOZ_ASSERT(!result.Failed());
69
0
    // Note that it's important to set the guard after Fill(), to make sure
70
0
    // that Fill() doesn't fail if aOther is immutable.
71
0
    mGuard = aOther.mGuard;
72
0
  }
73
74
  explicit InternalHeaders(const nsTArray<Entry>&& aHeaders,
75
                           HeadersGuardEnum aGuard = HeadersGuardEnum::None);
76
77
  InternalHeaders(const nsTArray<HeadersEntry>& aHeadersEntryList,
78
                  HeadersGuardEnum aGuard);
79
80
  void ToIPC(nsTArray<HeadersEntry>& aIPCHeaders,
81
             HeadersGuardEnum& aGuard);
82
83
  void Append(const nsACString& aName, const nsACString& aValue,
84
              ErrorResult& aRv);
85
  void Delete(const nsACString& aName, ErrorResult& aRv);
86
  void Get(const nsACString& aName, nsACString& aValue, ErrorResult& aRv) const;
87
  void GetFirst(const nsACString& aName, nsACString& aValue, ErrorResult& aRv) const;
88
  bool Has(const nsACString& aName, ErrorResult& aRv) const;
89
  void Set(const nsACString& aName, const nsACString& aValue, ErrorResult& aRv);
90
91
  uint32_t GetIterableLength()
92
0
  {
93
0
    MaybeSortList();
94
0
    return mSortedList.Length();
95
0
  }
96
  const NS_ConvertASCIItoUTF16 GetKeyAtIndex(unsigned aIndex)
97
0
  {
98
0
    MaybeSortList();
99
0
    MOZ_ASSERT(aIndex < mSortedList.Length());
100
0
    return NS_ConvertASCIItoUTF16(mSortedList[aIndex].mName);
101
0
  }
102
  const NS_ConvertASCIItoUTF16 GetValueAtIndex(unsigned aIndex)
103
0
  {
104
0
    MaybeSortList();
105
0
    MOZ_ASSERT(aIndex < mSortedList.Length());
106
0
    return NS_ConvertASCIItoUTF16(mSortedList[aIndex].mValue);
107
0
  }
108
109
  void Clear();
110
111
0
  HeadersGuardEnum Guard() const { return mGuard; }
112
  void SetGuard(HeadersGuardEnum aGuard, ErrorResult& aRv);
113
114
  void Fill(const InternalHeaders& aInit, ErrorResult& aRv);
115
  void Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& aRv);
116
  void Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv);
117
  void FillResponseHeaders(nsIRequest* aRequest);
118
119
  bool HasOnlySimpleHeaders() const;
120
121
  bool HasRevalidationHeaders() const;
122
123
  static already_AddRefed<InternalHeaders>
124
  BasicHeaders(InternalHeaders* aHeaders);
125
126
  static already_AddRefed<InternalHeaders>
127
  CORSHeaders(InternalHeaders* aHeaders);
128
129
  void
130
  GetEntries(nsTArray<InternalHeaders::Entry>& aEntries) const;
131
132
  void
133
  GetUnsafeHeaders(nsTArray<nsCString>& aNames) const;
134
private:
135
  virtual ~InternalHeaders();
136
137
  static bool IsInvalidName(const nsACString& aName, ErrorResult& aRv);
138
  static bool IsInvalidValue(const nsACString& aValue, ErrorResult& aRv);
139
  bool IsImmutable(ErrorResult& aRv) const;
140
  bool IsForbiddenRequestHeader(const nsACString& aName) const;
141
  bool IsForbiddenRequestNoCorsHeader(const nsACString& aName) const;
142
  bool IsForbiddenRequestNoCorsHeader(const nsACString& aName,
143
                                      const nsACString& aValue) const;
144
  bool IsForbiddenResponseHeader(const nsACString& aName) const;
145
146
  bool IsInvalidMutableHeader(const nsACString& aName,
147
                              ErrorResult& aRv) const
148
0
  {
149
0
    return IsInvalidMutableHeader(aName, EmptyCString(), aRv);
150
0
  }
151
152
  bool IsInvalidMutableHeader(const nsACString& aName,
153
                              const nsACString& aValue,
154
                              ErrorResult& aRv) const
155
0
  {
156
0
    return IsInvalidName(aName, aRv) ||
157
0
           IsInvalidValue(aValue, aRv) ||
158
0
           IsImmutable(aRv) ||
159
0
           IsForbiddenRequestHeader(aName) ||
160
0
           IsForbiddenRequestNoCorsHeader(aName, aValue) ||
161
0
           IsForbiddenResponseHeader(aName);
162
0
  }
163
164
  static bool IsSimpleHeader(const nsACString& aName,
165
                             const nsACString& aValue);
166
167
  static bool IsRevalidationHeader(const nsACString& aName);
168
169
  void MaybeSortList();
170
  void SetListDirty();
171
};
172
173
} // namespace dom
174
} // namespace mozilla
175
176
#endif // mozilla_dom_InternalHeaders_h