Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/net/MozURL.h
Line
Count
Source (jump to first uncovered line)
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#ifndef mozURL_h__
6
#define mozURL_h__
7
8
#include "mozilla/net/MozURL_ffi.h"
9
#include "mozilla/RefPtr.h"
10
11
namespace mozilla {
12
namespace net {
13
14
// This class provides a thread-safe, immutable URL parser.
15
// As long as there is RefPtr to the object, you may use it on any thread.
16
// The constructor is private. One can instantiate the object by
17
// calling the Init() method as such:
18
//
19
// RefPtr<MozURL> url;
20
// nsAutoCString href("http://example.com/path?query#ref");
21
// nsresult rv = MozURL::Init(getter_AddRefs(url), href);
22
// if (NS_SUCCEEDED(rv)) { /* use url */ }
23
//
24
// When changing the URL is needed, you need to call the Mutate() method.
25
// This gives you a Mutator object, on which you can perform setter operations.
26
// Calling Finalize() on the Mutator will result in a new MozURL and a status
27
// code. If any of the setter operations failed, it will be reflected in the
28
// status code, and a null MozURL.
29
//
30
// Note: In the case of a domain name containing non-ascii characters,
31
// GetSpec and GetHostname will return the IDNA(punycode) version of the host.
32
// Also note that for now, MozURL only supports the UTF-8 charset.
33
//
34
// Implementor Note: This type is only a holder for methods in C++, and does not
35
// reflect the actual layout of the type.
36
class MozURL final
37
{
38
public:
39
  static nsresult Init(MozURL** aURL, const nsACString& aSpec,
40
                       const MozURL* aBaseURL = nullptr)
41
0
  {
42
0
    return mozurl_new(aURL, &aSpec, aBaseURL);
43
0
  }
44
45
0
  nsDependentCSubstring Spec() const {
46
0
    return mozurl_spec(this);
47
0
  }
48
0
  nsDependentCSubstring Scheme() const {
49
0
    return mozurl_scheme(this);
50
0
  }
51
0
  nsDependentCSubstring Username() const {
52
0
    return mozurl_username(this);
53
0
  }
54
0
  nsDependentCSubstring Password() const {
55
0
    return mozurl_password(this);
56
0
  }
57
  // Will return the hostname of URL. If the hostname is an IPv6 address,
58
  // it will be enclosed in square brackets, such as `[::1]`
59
0
  nsDependentCSubstring Host() const {
60
0
    return mozurl_host(this);
61
0
  }
62
  // Will return the port number, if specified, or -1
63
0
  int32_t Port() const {
64
0
    return mozurl_port(this);
65
0
  }
66
  // If the URL's port number is equal to the default port, will only return the
67
  // hostname, otherwise it will return a string of the form `{host}:{port}`
68
  // See: https://url.spec.whatwg.org/#default-port
69
0
  nsDependentCSubstring HostPort() const {
70
0
    return mozurl_host_port(this);
71
0
  }
72
0
  nsDependentCSubstring FilePath() const {
73
0
    return mozurl_filepath(this);
74
0
  }
75
0
  nsDependentCSubstring Path() const {
76
0
    return mozurl_path(this);
77
0
  }
78
0
  nsDependentCSubstring Query() const {
79
0
    return mozurl_query(this);
80
0
  }
81
0
  nsDependentCSubstring Ref() const {
82
0
    return mozurl_fragment(this);
83
0
  }
84
0
  bool HasFragment() const {
85
0
    return mozurl_has_fragment(this);
86
0
  }
87
88
  // WARNING: This does not match the definition of origins in nsIPrincipal for
89
  // all URIs.
90
  // XXX: Consider bringing these implementations in sync with one-another?
91
0
  void Origin(nsACString& aOrigin) const {
92
0
    mozurl_origin(this, &aOrigin);
93
0
  }
94
95
0
  nsresult GetCommonBase(const MozURL* aOther, MozURL** aCommon) const {
96
0
    return mozurl_common_base(this, aOther, aCommon);
97
0
  }
98
0
  nsresult GetRelative(const MozURL* aOther, nsACString* aRelative) const {
99
0
    return mozurl_relative(this, aOther, aRelative);
100
0
  }
101
102
  class MOZ_STACK_CLASS Mutator
103
  {
104
  public:
105
    // Calling this method will result in the creation of a new MozURL that
106
    // adopts the mutator's mURL.
107
    // If any of the setters failed with an error code, that error code will be
108
    // returned here. It will also return an error code if Finalize is called
109
    // more than once on the Mutator.
110
0
    nsresult Finalize(MozURL** aURL) {
111
0
      nsresult rv = GetStatus();
112
0
      if (NS_SUCCEEDED(rv)) {
113
0
        mURL.forget(aURL);
114
0
      } else {
115
0
        *aURL = nullptr;
116
0
      }
117
0
      return rv;
118
0
    }
119
120
    // These setter methods will return a reference to `this` so that you may
121
    // chain setter operations as such:
122
    //
123
    // RefPtr<MozURL> url2;
124
    // nsresult rv = url->Mutate().SetHostname(NS_LITERAL_CSTRING("newhost"))
125
    //                            .SetFilePath(NS_LITERAL_CSTRING("new/file/path"))
126
    //                            .Finalize(getter_AddRefs(url2));
127
    // if (NS_SUCCEEDED(rv)) { /* use url2 */ }
128
0
    Mutator& SetScheme(const nsACString& aScheme) {
129
0
      if (NS_SUCCEEDED(GetStatus())) {
130
0
        mStatus = mozurl_set_scheme(mURL, &aScheme);
131
0
      }
132
0
      return *this;
133
0
    }
134
0
    Mutator& SetUsername(const nsACString& aUser) {
135
0
      if (NS_SUCCEEDED(GetStatus())) {
136
0
        mStatus = mozurl_set_username(mURL, &aUser);
137
0
      }
138
0
      return *this;
139
0
    }
140
0
    Mutator& SetPassword(const nsACString& aPassword) {
141
0
      if (NS_SUCCEEDED(GetStatus())) {
142
0
        mStatus = mozurl_set_password(mURL, &aPassword);
143
0
      }
144
0
      return *this;
145
0
    }
146
0
    Mutator& SetHostname(const nsACString& aHost) {
147
0
      if (NS_SUCCEEDED(GetStatus())) {
148
0
        mStatus = mozurl_set_hostname(mURL, &aHost);
149
0
      }
150
0
      return *this;
151
0
    }
152
0
    Mutator& SetHostPort(const nsACString& aHostPort) {
153
0
      if (NS_SUCCEEDED(GetStatus())) {
154
0
        mStatus = mozurl_set_host_port(mURL, &aHostPort);
155
0
      }
156
0
      return *this;
157
0
    }
158
0
    Mutator& SetFilePath(const nsACString& aPath) {
159
0
      if (NS_SUCCEEDED(GetStatus())) {
160
0
        mStatus = mozurl_set_pathname(mURL, &aPath);
161
0
      }
162
0
      return *this;
163
0
    }
164
0
    Mutator& SetQuery(const nsACString& aQuery) {
165
0
      if (NS_SUCCEEDED(GetStatus())) {
166
0
        mStatus = mozurl_set_query(mURL, &aQuery);
167
0
      }
168
0
      return *this;
169
0
    }
170
0
    Mutator& SetRef(const nsACString& aRef) {
171
0
      if (NS_SUCCEEDED(GetStatus())) {
172
0
        mStatus = mozurl_set_fragment(mURL, &aRef);
173
0
      }
174
0
      return *this;
175
0
    }
176
0
    Mutator& SetPort(int32_t aPort) {
177
0
      if (NS_SUCCEEDED(GetStatus())) {
178
0
        mStatus = mozurl_set_port_no(mURL, aPort);
179
0
      }
180
0
      return *this;
181
0
    }
182
183
    // This method returns the status code of the setter operations.
184
    // If any of the setters failed, it will return the code of the first error
185
    // that occured. If none of the setters failed, it will return NS_OK.
186
    // This method is useful to avoid doing expensive operations when the result
187
    // would not be used because an error occurred. For example:
188
    //
189
    // RefPtr<MozURL> url2;
190
    // MozURL::Mutator mut = url->Mutate();
191
    // mut.SetScheme("!@#$"); // this would fail
192
    // if (NS_SUCCEDED(mut.GetStatus())) {
193
    //   nsAutoCString host(ExpensiveComputing());
194
    //   rv = mut.SetHostname(host).Finalize(getter_AddRefs(url2));
195
    // }
196
    // if (NS_SUCCEEDED(rv)) { /* use url2 */ }
197
0
    nsresult GetStatus() {
198
0
      return mURL ? mStatus : NS_ERROR_NOT_AVAILABLE;
199
0
    }
200
  private:
201
0
    explicit Mutator(MozURL* aUrl) : mStatus(NS_OK) {
202
0
      mozurl_clone(aUrl, getter_AddRefs(mURL));
203
0
    }
204
    RefPtr<MozURL> mURL;
205
    nsresult mStatus;
206
    friend class MozURL;
207
  };
208
209
0
  Mutator Mutate() { return Mutator(this); }
210
211
  // AddRef and Release are non-virtual on this type, and always call into rust.
212
0
  nsrefcnt AddRef() {
213
0
    return mozurl_addref(this);
214
0
  }
215
0
  nsrefcnt Release() {
216
0
    return mozurl_release(this);
217
0
  }
218
219
private:
220
  // Make it a compile time error for C++ code to ever create, destruct, or copy
221
  // MozURL objects. All of these operations will be performed by rust.
222
  MozURL(); /* never defined */
223
  ~MozURL(); /* never defined */
224
  MozURL(const MozURL&) = delete;
225
  MozURL& operator=(const MozURL&) = delete;
226
};
227
228
} // namespace net
229
} // namespace mozilla
230
231
#endif // mozURL_h__