xref: /aosp_15_r20/external/sandboxed-api/contrib/uriparser/utils/utils_uriparser.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1*ec63e07aSXin Li // Copyright 2022 Google LLC
2*ec63e07aSXin Li //
3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li // you may not use this file except in compliance with the License.
5*ec63e07aSXin Li // You may obtain a copy of the License at
6*ec63e07aSXin Li //
7*ec63e07aSXin Li //     https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li //
9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li // See the License for the specific language governing permissions and
13*ec63e07aSXin Li // limitations under the License.
14*ec63e07aSXin Li 
15*ec63e07aSXin Li #include "contrib/uriparser/utils/utils_uriparser.h"
16*ec63e07aSXin Li 
17*ec63e07aSXin Li #include <arpa/inet.h>
18*ec63e07aSXin Li #include <netinet/in.h>
19*ec63e07aSXin Li #include <sys/socket.h>
20*ec63e07aSXin Li 
21*ec63e07aSXin Li #include <fstream>
22*ec63e07aSXin Li #include <iostream>
23*ec63e07aSXin Li #include <string>
24*ec63e07aSXin Li 
25*ec63e07aSXin Li #include "absl/cleanup/cleanup.h"
26*ec63e07aSXin Li 
~UriParser()27*ec63e07aSXin Li UriParser::~UriParser() {
28*ec63e07aSXin Li   if (GetStatus().ok()) {
29*ec63e07aSXin Li     api_.uriFreeUriMembersA(uri_.PtrBefore()).IgnoreError();
30*ec63e07aSXin Li   }
31*ec63e07aSXin Li }
32*ec63e07aSXin Li 
GetStatus()33*ec63e07aSXin Li absl::Status UriParser::GetStatus() { return status_; }
34*ec63e07aSXin Li 
ParseUri()35*ec63e07aSXin Li absl::Status UriParser::ParseUri() {
36*ec63e07aSXin Li   SAPI_RETURN_IF_ERROR(sandbox_->Allocate(&uri_, true));
37*ec63e07aSXin Li 
38*ec63e07aSXin Li   sapi::v::Struct<UriParserStateA> state;
39*ec63e07aSXin Li   state.mutable_data()->uri = reinterpret_cast<UriUriA*>(uri_.GetRemote());
40*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(
41*ec63e07aSXin Li       int ret, api_.uriParseUriA(state.PtrBefore(), c_uri_.PtrBefore()));
42*ec63e07aSXin Li   if (ret != 0) {
43*ec63e07aSXin Li     return absl::UnavailableError("Unable to parse uri");
44*ec63e07aSXin Li   }
45*ec63e07aSXin Li 
46*ec63e07aSXin Li   SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&uri_));
47*ec63e07aSXin Li 
48*ec63e07aSXin Li   return absl::OkStatus();
49*ec63e07aSXin Li }
50*ec63e07aSXin Li 
FetchUriText(UriTextRangeA * ptr)51*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::FetchUriText(UriTextRangeA* ptr) {
52*ec63e07aSXin Li   if (ptr == nullptr) {
53*ec63e07aSXin Li     return "";
54*ec63e07aSXin Li   }
55*ec63e07aSXin Li   if (ptr->first == nullptr) {
56*ec63e07aSXin Li     return "";
57*ec63e07aSXin Li   }
58*ec63e07aSXin Li 
59*ec63e07aSXin Li   size_t size = ptr->afterLast - ptr->first;
60*ec63e07aSXin Li 
61*ec63e07aSXin Li   // Sometimes uriparser dosen't allocate new memory
62*ec63e07aSXin Li   // and sometimes it does.
63*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(
64*ec63e07aSXin Li       std::string uri,
65*ec63e07aSXin Li       sandbox_->GetCString(sapi::v::RemotePtr(const_cast<char*>(ptr->first))));
66*ec63e07aSXin Li 
67*ec63e07aSXin Li   return uri.substr(0, size);
68*ec63e07aSXin Li }
69*ec63e07aSXin Li 
GetScheme()70*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetScheme() {
71*ec63e07aSXin Li   return FetchUriText(&uri_.mutable_data()->scheme);
72*ec63e07aSXin Li }
73*ec63e07aSXin Li 
GetUserInfo()74*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetUserInfo() {
75*ec63e07aSXin Li   return FetchUriText(&uri_.mutable_data()->userInfo);
76*ec63e07aSXin Li }
77*ec63e07aSXin Li 
GetHostText()78*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetHostText() {
79*ec63e07aSXin Li   return FetchUriText(&uri_.mutable_data()->hostText);
80*ec63e07aSXin Li }
81*ec63e07aSXin Li 
GetHostIP()82*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetHostIP() {
83*ec63e07aSXin Li   char ipstr[INET6_ADDRSTRLEN] = "";
84*ec63e07aSXin Li 
85*ec63e07aSXin Li   UriHostDataA* data = &uri_.mutable_data()->hostData;
86*ec63e07aSXin Li 
87*ec63e07aSXin Li   if (uri_.mutable_data()->hostData.ip4) {
88*ec63e07aSXin Li     sapi::v::Struct<UriIp4> ip4;
89*ec63e07aSXin Li     ip4.SetRemote(uri_.mutable_data()->hostData.ip4);
90*ec63e07aSXin Li     SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&ip4));
91*ec63e07aSXin Li     inet_ntop(AF_INET, ip4.mutable_data()->data, ipstr, sizeof(ipstr));
92*ec63e07aSXin Li   } else if (uri_.mutable_data()->hostData.ip6) {
93*ec63e07aSXin Li     sapi::v::Struct<UriIp6> ip6;
94*ec63e07aSXin Li     ip6.SetRemote(uri_.mutable_data()->hostData.ip6);
95*ec63e07aSXin Li     SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&ip6));
96*ec63e07aSXin Li     inet_ntop(AF_INET6, ip6.mutable_data()->data, ipstr, sizeof(ipstr));
97*ec63e07aSXin Li   }
98*ec63e07aSXin Li 
99*ec63e07aSXin Li   return std::string(ipstr);
100*ec63e07aSXin Li }
101*ec63e07aSXin Li 
GetPortText()102*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetPortText() {
103*ec63e07aSXin Li   return FetchUriText(&uri_.mutable_data()->portText);
104*ec63e07aSXin Li }
105*ec63e07aSXin Li 
GetQuery()106*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetQuery() {
107*ec63e07aSXin Li   return FetchUriText(&uri_.mutable_data()->query);
108*ec63e07aSXin Li }
109*ec63e07aSXin Li 
GetFragment()110*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetFragment() {
111*ec63e07aSXin Li   return FetchUriText(&uri_.mutable_data()->fragment);
112*ec63e07aSXin Li }
113*ec63e07aSXin Li 
GetPath()114*ec63e07aSXin Li absl::StatusOr<std::vector<std::string>> UriParser::GetPath() {
115*ec63e07aSXin Li   std::vector<std::string> ret;
116*ec63e07aSXin Li 
117*ec63e07aSXin Li   UriPathSegmentA* pathHead = uri_.mutable_data()->pathHead;
118*ec63e07aSXin Li   if (pathHead == nullptr) {
119*ec63e07aSXin Li     return ret;
120*ec63e07aSXin Li   }
121*ec63e07aSXin Li 
122*ec63e07aSXin Li   sapi::v::Struct<UriPathSegmentA> path_segment;
123*ec63e07aSXin Li   path_segment.SetRemote(pathHead);
124*ec63e07aSXin Li 
125*ec63e07aSXin Li   while (path_segment.GetRemote() != nullptr) {
126*ec63e07aSXin Li     SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&path_segment));
127*ec63e07aSXin Li 
128*ec63e07aSXin Li     SAPI_ASSIGN_OR_RETURN(std::string seg,
129*ec63e07aSXin Li                           FetchUriText(&path_segment.mutable_data()->text));
130*ec63e07aSXin Li     if (!seg.empty()) {
131*ec63e07aSXin Li       ret.push_back(seg);
132*ec63e07aSXin Li     }
133*ec63e07aSXin Li 
134*ec63e07aSXin Li     path_segment.SetRemote(path_segment.mutable_data()->next);
135*ec63e07aSXin Li   }
136*ec63e07aSXin Li 
137*ec63e07aSXin Li   return ret;
138*ec63e07aSXin Li }
139*ec63e07aSXin Li 
NormalizeSyntax()140*ec63e07aSXin Li absl::Status UriParser::NormalizeSyntax() {
141*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(int dirty_parts,
142*ec63e07aSXin Li                         api_.uriNormalizeSyntaxMaskRequiredA(uri_.PtrNone()));
143*ec63e07aSXin Li 
144*ec63e07aSXin Li   return NormalizeSyntax(dirty_parts);
145*ec63e07aSXin Li }
146*ec63e07aSXin Li 
NormalizeSyntax(int norm_mask)147*ec63e07aSXin Li absl::Status UriParser::NormalizeSyntax(int norm_mask) {
148*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(int ret,
149*ec63e07aSXin Li                         api_.uriNormalizeSyntaxExA(uri_.PtrAfter(), norm_mask));
150*ec63e07aSXin Li 
151*ec63e07aSXin Li   if (ret != 0) {
152*ec63e07aSXin Li     return absl::UnavailableError("Unable to normalize");
153*ec63e07aSXin Li   }
154*ec63e07aSXin Li 
155*ec63e07aSXin Li   return absl::OkStatus();
156*ec63e07aSXin Li }
157*ec63e07aSXin Li 
GetUri()158*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetUri() { return GetUri(&uri_); }
159*ec63e07aSXin Li 
GetUri(sapi::v::Struct<UriUriA> * uri)160*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetUri(sapi::v::Struct<UriUriA>* uri) {
161*ec63e07aSXin Li   sapi::v::Int size;
162*ec63e07aSXin Li   int ret;
163*ec63e07aSXin Li 
164*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(
165*ec63e07aSXin Li       ret, api_.uriToStringCharsRequiredA(uri->PtrNone(), size.PtrAfter()));
166*ec63e07aSXin Li   if (ret != 0) {
167*ec63e07aSXin Li     return absl::UnavailableError("Unable to get size");
168*ec63e07aSXin Li   }
169*ec63e07aSXin Li 
170*ec63e07aSXin Li   sapi::v::Array<char> buf(size.GetValue() + 1);
171*ec63e07aSXin Li   sapi::v::NullPtr null_ptr;
172*ec63e07aSXin Li 
173*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(ret, api_.uriToStringA(buf.PtrAfter(), uri->PtrNone(),
174*ec63e07aSXin Li                                                buf.GetSize(), &null_ptr));
175*ec63e07aSXin Li   if (ret != 0) {
176*ec63e07aSXin Li     return absl::UnavailableError("Unable to Recomposing URI");
177*ec63e07aSXin Li   }
178*ec63e07aSXin Li 
179*ec63e07aSXin Li   return std::string(buf.GetData());
180*ec63e07aSXin Li }
181*ec63e07aSXin Li 
GetUriEscaped(bool space_to_plus,bool normalize_breaks)182*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetUriEscaped(bool space_to_plus,
183*ec63e07aSXin Li                                                      bool normalize_breaks) {
184*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(std::string uri, GetUri());
185*ec63e07aSXin Li 
186*ec63e07aSXin Li   // Be sure to allocate *6 times* the space of the input buffer for
187*ec63e07aSXin Li   // *6 times* for _normalizeBreaks == URI_TRUE_
188*ec63e07aSXin Li   int space = uri.length() * 6 + 1;
189*ec63e07aSXin Li 
190*ec63e07aSXin Li   sapi::v::Array<char> bufout(space);
191*ec63e07aSXin Li   sapi::v::ConstCStr bufin(uri.c_str());
192*ec63e07aSXin Li 
193*ec63e07aSXin Li   SAPI_RETURN_IF_ERROR(api_.uriEscapeA(bufin.PtrBefore(), bufout.PtrAfter(),
194*ec63e07aSXin Li                                        space_to_plus, normalize_breaks));
195*ec63e07aSXin Li 
196*ec63e07aSXin Li   return std::string(bufout.GetData());
197*ec63e07aSXin Li }
198*ec63e07aSXin Li 
GetUriWithBase(const std::string & base)199*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetUriWithBase(const std::string& base) {
200*ec63e07aSXin Li   UriParser base_uri(sandbox_, base);
201*ec63e07aSXin Li 
202*ec63e07aSXin Li   sapi::v::Struct<UriUriA> newuri;
203*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(int ret,
204*ec63e07aSXin Li                         api_.uriAddBaseUriA(newuri.PtrAfter(), uri_.PtrNone(),
205*ec63e07aSXin Li                                             base_uri.uri_.PtrBefore()));
206*ec63e07aSXin Li   if (ret != 0) {
207*ec63e07aSXin Li     return absl::UnavailableError("Unable to add base");
208*ec63e07aSXin Li   }
209*ec63e07aSXin Li   absl::Cleanup newuri_cleanup = [this, &newuri] {
210*ec63e07aSXin Li     api_.uriFreeUriMembersA(newuri.PtrNone()).IgnoreError();
211*ec63e07aSXin Li   };
212*ec63e07aSXin Li 
213*ec63e07aSXin Li   return GetUri(&newuri);
214*ec63e07aSXin Li }
215*ec63e07aSXin Li 
GetUriWithoutBase(const std::string & base,bool domain_root_mode)216*ec63e07aSXin Li absl::StatusOr<std::string> UriParser::GetUriWithoutBase(
217*ec63e07aSXin Li     const std::string& base, bool domain_root_mode) {
218*ec63e07aSXin Li   UriParser base_uri(sandbox_, base);
219*ec63e07aSXin Li 
220*ec63e07aSXin Li   sapi::v::Struct<UriUriA> newuri;
221*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(
222*ec63e07aSXin Li       int ret,
223*ec63e07aSXin Li       api_.uriRemoveBaseUriA(newuri.PtrAfter(), uri_.PtrNone(),
224*ec63e07aSXin Li                              base_uri.uri_.PtrBefore(), domain_root_mode));
225*ec63e07aSXin Li   if (ret != 0) {
226*ec63e07aSXin Li     return absl::UnavailableError("Unable to remove base");
227*ec63e07aSXin Li   }
228*ec63e07aSXin Li   absl::Cleanup newuri_cleanup = [this, &newuri] {
229*ec63e07aSXin Li     api_.uriFreeUriMembersA(newuri.PtrNone()).IgnoreError();
230*ec63e07aSXin Li   };
231*ec63e07aSXin Li 
232*ec63e07aSXin Li   return GetUri(&newuri);
233*ec63e07aSXin Li }
234*ec63e07aSXin Li 
235*ec63e07aSXin Li absl::StatusOr<absl::btree_map<std::string, std::string>>
GetQueryElements()236*ec63e07aSXin Li UriParser::GetQueryElements() {
237*ec63e07aSXin Li   absl::btree_map<std::string, std::string> outquery;
238*ec63e07aSXin Li 
239*ec63e07aSXin Li   if (uri_.mutable_data()->query.first == nullptr) {
240*ec63e07aSXin Li     return outquery;
241*ec63e07aSXin Li   }
242*ec63e07aSXin Li 
243*ec63e07aSXin Li   sapi::v::Array<void*> query_ptr(1);
244*ec63e07aSXin Li   sapi::v::Int query_count;
245*ec63e07aSXin Li   sapi::v::RemotePtr first(const_cast<char*>(uri_.mutable_data()->query.first));
246*ec63e07aSXin Li   sapi::v::RemotePtr afterLast(
247*ec63e07aSXin Li       const_cast<char*>(uri_.mutable_data()->query.afterLast));
248*ec63e07aSXin Li 
249*ec63e07aSXin Li   SAPI_ASSIGN_OR_RETURN(
250*ec63e07aSXin Li       int ret,
251*ec63e07aSXin Li       api_.uriDissectQueryMallocA(query_ptr.PtrAfter(), query_count.PtrAfter(),
252*ec63e07aSXin Li                                   &first, &afterLast));
253*ec63e07aSXin Li   if (ret != 0) {
254*ec63e07aSXin Li     return absl::UnavailableError("Unable to get query list");
255*ec63e07aSXin Li   }
256*ec63e07aSXin Li   absl::Cleanup query_list_cleanup = [this, &query_ptr] {
257*ec63e07aSXin Li     sapi::v::RemotePtr rptr(query_ptr[0]);
258*ec63e07aSXin Li     api_.uriFreeQueryListA(&rptr).IgnoreError();
259*ec63e07aSXin Li   };
260*ec63e07aSXin Li 
261*ec63e07aSXin Li   sapi::v::Struct<UriQueryListA> obj;
262*ec63e07aSXin Li   obj.SetRemote(query_ptr[0]);
263*ec63e07aSXin Li 
264*ec63e07aSXin Li   for (int i = 0; i < query_count.GetValue(); ++i) {
265*ec63e07aSXin Li     SAPI_RETURN_IF_ERROR(sandbox_->TransferFromSandboxee(&obj));
266*ec63e07aSXin Li     obj.SetRemote(nullptr);
267*ec63e07aSXin Li 
268*ec63e07aSXin Li     void* key_p = const_cast<char*>(obj.mutable_data()->key);
269*ec63e07aSXin Li     void* value_p = const_cast<char*>(obj.mutable_data()->value);
270*ec63e07aSXin Li 
271*ec63e07aSXin Li     SAPI_ASSIGN_OR_RETURN(std::string key_s,
272*ec63e07aSXin Li                           sandbox_->GetCString(sapi::v::RemotePtr(key_p)));
273*ec63e07aSXin Li     std::string value_s;
274*ec63e07aSXin Li     if (value_p != nullptr) {
275*ec63e07aSXin Li       SAPI_ASSIGN_OR_RETURN(value_s,
276*ec63e07aSXin Li                             sandbox_->GetCString(sapi::v::RemotePtr(value_p)));
277*ec63e07aSXin Li     } else {
278*ec63e07aSXin Li       value_s = "";
279*ec63e07aSXin Li     }
280*ec63e07aSXin Li     outquery[key_s] = value_s;
281*ec63e07aSXin Li     obj.SetRemote(obj.mutable_data()->next);
282*ec63e07aSXin Li   }
283*ec63e07aSXin Li   obj.SetRemote(nullptr);
284*ec63e07aSXin Li 
285*ec63e07aSXin Li   return outquery;
286*ec63e07aSXin Li }
287