• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "file_uri_n_exporter.h"
16 
17 #include <string>
18 #include <vector>
19 
20 #include "file_uri_entity.h"
21 #include "file_utils.h"
22 #include "log.h"
23 #include "uri.h"
24 #include "sandbox_helper.h"
25 
26 using namespace std;
27 namespace OHOS {
28 namespace AppFileService {
29 namespace ModuleFileUri {
30 using namespace FileManagement;
31 using namespace FileManagement::LibN;
32 const std::string MEDIA_AUTHORITY = "media";
Constructor(napi_env env,napi_callback_info info)33 napi_value FileUriNExporter::Constructor(napi_env env, napi_callback_info info)
34 {
35     NFuncArg funcArg(env, info);
36     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
37         LOGE("Number of arguments unmatched");
38         NError(EINVAL).ThrowErr(env);
39         return nullptr;
40     }
41     auto [succPath, path, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String();
42     if (!succPath) {
43         LOGE("Failed to get path");
44         NError(EINVAL).ThrowErr(env);
45         return nullptr;
46     }
47     auto fileuriEntity = CreateUniquePtr<FileUriEntity>(string(path.get()));
48     if (fileuriEntity == nullptr) {
49         LOGE("Failed to request heap memory.");
50         NError(ENOMEM).ThrowErr(env);
51         return nullptr;
52     }
53     if (!NClass::SetEntityFor<FileUriEntity>(env, funcArg.GetThisVar(), move(fileuriEntity))) {
54         LOGE("Failed to set file entity");
55         NError(EIO).ThrowErr(env);
56         return nullptr;
57     }
58     return funcArg.GetThisVar();
59 }
60 
UriToString(napi_env env,napi_callback_info info)61 napi_value FileUriNExporter::UriToString(napi_env env, napi_callback_info info)
62 {
63     NFuncArg funcArg(env, info);
64     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
65         LOGE("Number of arguments unmatched");
66         NError(EINVAL).ThrowErr(env);
67         return nullptr;
68     }
69     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
70     if (!fileuriEntity) {
71         LOGE("Failed to get file entity");
72         NError(EINVAL).ThrowErr(env);
73         return nullptr;
74     }
75     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.ToString()).val_;
76 }
77 
GetFileUriName(napi_env env,napi_callback_info info)78 napi_value FileUriNExporter::GetFileUriName(napi_env env, napi_callback_info info)
79 {
80     NFuncArg funcArg(env, info);
81     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
82         LOGE("Number of arguments unmatched");
83         NError(EINVAL).ThrowErr(env);
84         return nullptr;
85     }
86     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
87     if (!fileuriEntity) {
88         LOGE("Failed to get file entity");
89         NError(EINVAL).ThrowErr(env);
90         return nullptr;
91     }
92     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.GetName()).val_;
93 }
94 
GetFullDirectoryUri(napi_env env,napi_callback_info info)95 napi_value FileUriNExporter::GetFullDirectoryUri(napi_env env, napi_callback_info info)
96 {
97     NFuncArg funcArg(env, info);
98     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
99         LOGE("Number of arguments unmatched");
100         NError(E_PARAMS).ThrowErr(env);
101         return nullptr;
102     }
103     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
104     if (!fileuriEntity) {
105         LOGE("Failed to get file entity");
106         NError(EINVAL).ThrowErr(env);
107         return nullptr;
108     }
109     string uri = fileuriEntity->fileUri_.GetFullDirectoryUri();
110     if (uri == "") {
111         LOGE("No such file or directory!");
112         NError(ENOENT).ThrowErr(env);
113     }
114     return NVal::CreateUTF8String(env, uri).val_;
115 }
116 
IsRemoteUri(napi_env env,napi_callback_info info)117 napi_value FileUriNExporter::IsRemoteUri(napi_env env, napi_callback_info info)
118 {
119     NFuncArg funcArg(env, info);
120     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
121         LOGE("Number of arguments unmatched");
122         NError(E_PARAMS).ThrowErr(env);
123         return nullptr;
124     }
125     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
126     if (!fileuriEntity) {
127         LOGE("Failed to get file entity");
128         NError(EINVAL).ThrowErr(env);
129         return nullptr;
130     }
131     bool isRemoteUri = fileuriEntity->fileUri_.IsRemoteUri();
132     return NVal::CreateBool(env, isRemoteUri).val_;
133 }
134 
GetFileUriPath(napi_env env,napi_callback_info info)135 napi_value FileUriNExporter::GetFileUriPath(napi_env env, napi_callback_info info)
136 {
137     NFuncArg funcArg(env, info);
138     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
139         LOGE("Number of arguments unmatched");
140         NError(EINVAL).ThrowErr(env);
141         return nullptr;
142     }
143     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
144     if (!fileuriEntity) {
145         LOGE("Failed to get file entity");
146         NError(EINVAL).ThrowErr(env);
147         return nullptr;
148     }
149     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.GetRealPath()).val_;
150 }
151 
Split(const std::string & path,Uri & uri)152 static std::string Split(const std::string &path, Uri &uri)
153 {
154     std::string normalizeUri = "";
155     if (!uri.GetScheme().empty()) {
156         normalizeUri += uri.GetScheme() + ":";
157     }
158     if (uri.GetPath().empty()) {
159         normalizeUri += uri.GetSchemeSpecificPart();
160     } else {
161         if (!uri.GetHost().empty()) {
162             normalizeUri += "//";
163             if (!uri.GetUserInfo().empty()) {
164                 normalizeUri += uri.GetUserInfo() + "@";
165             }
166             normalizeUri += uri.GetHost();
167             if (uri.GetPort() != -1) {
168                 normalizeUri += ":" + std::to_string(uri.GetPort());
169             }
170         } else if (!uri.GetAuthority().empty()) {
171             normalizeUri += "//" + uri.GetAuthority();
172         }
173         normalizeUri += path;
174     }
175     if (!uri.GetQuery().empty()) {
176         normalizeUri += "?" + uri.GetQuery();
177     }
178     if (!uri.GetFragment().empty()) {
179         normalizeUri += "#" + uri.GetFragment();
180     }
181     return normalizeUri;
182 }
183 
NormalizeUri(Uri & uri)184 static std::string NormalizeUri(Uri &uri)
185 {
186     std::vector<std::string> temp;
187     size_t pathLen = uri.GetPath().size();
188     if (pathLen == 0) {
189         return uri.ToString();
190     }
191     size_t pos = 0;
192     size_t left = 0;
193     while ((pos = uri.GetPath().find('/', left)) != std::string::npos) {
194         temp.emplace_back(uri.GetPath().substr(left, pos - left));
195         left = pos + 1;
196     }
197     if (left != pathLen) {
198         temp.emplace_back(uri.GetPath().substr(left));
199     }
200     size_t tempLen = temp.size();
201     std::vector<std::string> normalizeTemp;
202     for (size_t i = 0; i < tempLen; ++i) {
203         if (!temp[i].empty() && !(temp[i] == ".") && !(temp[i] == "..")) {
204             normalizeTemp.emplace_back(temp[i]);
205         }
206         if (temp[i] == "..") {
207             if (!normalizeTemp.empty() && normalizeTemp.back() != "..") {
208                 normalizeTemp.pop_back();
209             } else {
210                 normalizeTemp.emplace_back(temp[i]);
211             }
212         }
213     }
214     std::string normalizePath = "";
215     tempLen = normalizeTemp.size();
216     if (tempLen == 0) {
217         normalizePath = "/";
218     } else {
219         for (size_t i = 0; i < tempLen; ++i) {
220             normalizePath += "/" + normalizeTemp[i];
221         }
222     }
223     return Split(normalizePath, uri);
224 }
225 
Normalize(napi_env env,napi_callback_info info)226 napi_value FileUriNExporter::Normalize(napi_env env, napi_callback_info info)
227 {
228     NFuncArg funcArg(env, info);
229     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
230         LOGE("Number of arguments unmatched");
231         NError(EINVAL).ThrowErr(env);
232         return nullptr;
233     }
234     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
235     if (!fileuriEntity) {
236         LOGE("Failed to get file entity");
237         NError(EINVAL).ThrowErr(env);
238         return nullptr;
239     }
240 
241     napi_value uriObj = NClass::InstantiateClass(env, FileUriNExporter::className,
242         {NVal::CreateUTF8String(env, NormalizeUri(fileuriEntity->fileUri_.uri_)).val_});
243     if (!uriObj) {
244         LOGE("Failed to construct FileUriNExporter.");
245         NError(E_UNKNOWN_ERROR).ThrowErr(env);
246         return nullptr;
247     }
248 
249     return uriObj;
250 }
251 
Equals(napi_env env,napi_callback_info info)252 napi_value FileUriNExporter::Equals(napi_env env, napi_callback_info info)
253 {
254     NFuncArg funcArg(env, info);
255     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
256         LOGE("Number of arguments unmatched");
257         NError(EINVAL).ThrowErr(env);
258         return nullptr;
259     }
260     auto thisEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
261     if (!thisEntity) {
262         LOGE("Failed to get file entity");
263         NError(EINVAL).ThrowErr(env);
264         return nullptr;
265     }
266 
267     auto otherEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg[NARG_POS::FIRST]);
268     if (!otherEntity) {
269         LOGE("Failed to get file entity");
270         NError(EINVAL).ThrowErr(env);
271         return nullptr;
272     }
273 
274     return NVal::CreateBool(env, thisEntity->fileUri_.uri_.Equals(otherEntity->fileUri_.uri_)).val_;
275 }
276 
EqualsTo(napi_env env,napi_callback_info info)277 napi_value FileUriNExporter::EqualsTo(napi_env env, napi_callback_info info)
278 {
279     NFuncArg funcArg(env, info);
280     if (!funcArg.InitArgs(NARG_CNT::ONE)) {
281         LOGE("Number of arguments unmatched");
282         NError(E_PARAMS).ThrowErr(env);
283         return nullptr;
284     }
285     auto thisEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
286     if (!thisEntity) {
287         LOGE("Failed to get file entity");
288         NError(E_PARAMS).ThrowErr(env);
289         return nullptr;
290     }
291 
292     auto otherEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg[NARG_POS::FIRST]);
293     if (!otherEntity) {
294         LOGE("Failed to get file entity");
295         NError(E_PARAMS).ThrowErr(env);
296         return nullptr;
297     }
298     return NVal::CreateBool(env, thisEntity->fileUri_.uri_.Equals(otherEntity->fileUri_.uri_)).val_;
299 }
300 
IsAbsolute(napi_env env,napi_callback_info info)301 napi_value FileUriNExporter::IsAbsolute(napi_env env, napi_callback_info info)
302 {
303     NFuncArg funcArg(env, info);
304     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
305         LOGE("Number of arguments unmatched");
306         NError(EINVAL).ThrowErr(env);
307         return nullptr;
308     }
309     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
310     if (!fileuriEntity) {
311         LOGE("Failed to get file entity");
312         NError(EINVAL).ThrowErr(env);
313         return nullptr;
314     }
315     return NVal::CreateBool(env, fileuriEntity->fileUri_.uri_.IsAbsolute()).val_;
316 }
317 
GetScheme(napi_env env,napi_callback_info info)318 napi_value FileUriNExporter::GetScheme(napi_env env, napi_callback_info info)
319 {
320     NFuncArg funcArg(env, info);
321     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
322         LOGE("Number of arguments unmatched");
323         NError(EINVAL).ThrowErr(env);
324         return nullptr;
325     }
326     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
327     if (!fileuriEntity) {
328         LOGE("Failed to get file entity");
329         NError(EINVAL).ThrowErr(env);
330         return nullptr;
331     }
332 
333     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.uri_.GetScheme()).val_;
334 }
335 
GetAuthority(napi_env env,napi_callback_info info)336 napi_value FileUriNExporter::GetAuthority(napi_env env, napi_callback_info info)
337 {
338     NFuncArg funcArg(env, info);
339     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
340         LOGE("Number of arguments unmatched");
341         NError(EINVAL).ThrowErr(env);
342         return nullptr;
343     }
344     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
345     if (!fileuriEntity) {
346         LOGE("Failed to get file entity");
347         NError(EINVAL).ThrowErr(env);
348         return nullptr;
349     }
350 
351     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.uri_.GetAuthority()).val_;
352 }
353 
GetSsp(napi_env env,napi_callback_info info)354 napi_value FileUriNExporter::GetSsp(napi_env env, napi_callback_info info)
355 {
356     NFuncArg funcArg(env, info);
357     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
358         LOGE("Number of arguments unmatched");
359         NError(EINVAL).ThrowErr(env);
360         return nullptr;
361     }
362     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
363     if (!fileuriEntity) {
364         LOGE("Failed to get file entity");
365         NError(EINVAL).ThrowErr(env);
366         return nullptr;
367     }
368 
369     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.uri_.GetSchemeSpecificPart()).val_;
370 }
371 
GetUserInfo(napi_env env,napi_callback_info info)372 napi_value FileUriNExporter::GetUserInfo(napi_env env, napi_callback_info info)
373 {
374     NFuncArg funcArg(env, info);
375     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
376         LOGE("Number of arguments unmatched");
377         NError(EINVAL).ThrowErr(env);
378         return nullptr;
379     }
380     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
381     if (!fileuriEntity) {
382         LOGE("Failed to get file entity");
383         NError(EINVAL).ThrowErr(env);
384         return nullptr;
385     }
386 
387     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.uri_.GetUserInfo()).val_;
388 }
389 
GetHost(napi_env env,napi_callback_info info)390 napi_value FileUriNExporter::GetHost(napi_env env, napi_callback_info info)
391 {
392     NFuncArg funcArg(env, info);
393     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
394         LOGE("Number of arguments unmatched");
395         NError(EINVAL).ThrowErr(env);
396         return nullptr;
397     }
398     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
399     if (!fileuriEntity) {
400         LOGE("Failed to get file entity");
401         NError(EINVAL).ThrowErr(env);
402         return nullptr;
403     }
404 
405     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.uri_.GetHost()).val_;
406 }
407 
GetPort(napi_env env,napi_callback_info info)408 napi_value FileUriNExporter::GetPort(napi_env env, napi_callback_info info)
409 {
410     NFuncArg funcArg(env, info);
411     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
412         LOGE("Number of arguments unmatched");
413         NError(EINVAL).ThrowErr(env);
414         return nullptr;
415     }
416     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
417     if (!fileuriEntity) {
418         LOGE("Failed to get file entity");
419         NError(EINVAL).ThrowErr(env);
420         return nullptr;
421     }
422 
423     return NVal::CreateUTF8String(env, to_string(fileuriEntity->fileUri_.uri_.GetPort())).val_;
424 }
425 
GetQuery(napi_env env,napi_callback_info info)426 napi_value FileUriNExporter::GetQuery(napi_env env, napi_callback_info info)
427 {
428     NFuncArg funcArg(env, info);
429     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
430         LOGE("Number of arguments unmatched");
431         NError(EINVAL).ThrowErr(env);
432         return nullptr;
433     }
434     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
435     if (!fileuriEntity) {
436         LOGE("Failed to get file entity");
437         NError(EINVAL).ThrowErr(env);
438         return nullptr;
439     }
440 
441     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.uri_.GetQuery()).val_;
442 }
443 
GetFragment(napi_env env,napi_callback_info info)444 napi_value FileUriNExporter::GetFragment(napi_env env, napi_callback_info info)
445 {
446     NFuncArg funcArg(env, info);
447     if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
448         LOGE("Number of arguments unmatched");
449         NError(EINVAL).ThrowErr(env);
450         return nullptr;
451     }
452     auto fileuriEntity = NClass::GetEntityOf<FileUriEntity>(env, funcArg.GetThisVar());
453     if (!fileuriEntity) {
454         LOGE("Failed to get file entity");
455         NError(EINVAL).ThrowErr(env);
456         return nullptr;
457     }
458 
459     return NVal::CreateUTF8String(env, fileuriEntity->fileUri_.uri_.GetFragment()).val_;
460 }
461 
Export()462 bool FileUriNExporter::Export()
463 {
464     vector<napi_property_descriptor> props = {
465         NVal::DeclareNapiFunction("toString", UriToString),
466         NVal::DeclareNapiGetter("name", GetFileUriName),
467         NVal::DeclareNapiGetter("path", GetFileUriPath),
468         NVal::DeclareNapiFunction("getFullDirectoryUri", GetFullDirectoryUri),
469         NVal::DeclareNapiFunction("isRemoteUri", IsRemoteUri),
470         NVal::DeclareNapiFunction("normalize", Normalize),
471         NVal::DeclareNapiFunction("equals", Equals),
472         NVal::DeclareNapiFunction("equalsTo", EqualsTo),
473         NVal::DeclareNapiFunction("checkIsAbsolute", IsAbsolute),
474         NVal::DeclareNapiGetter("scheme", GetScheme),
475         NVal::DeclareNapiGetter("authority", GetAuthority),
476         NVal::DeclareNapiGetter("ssp", GetSsp),
477         NVal::DeclareNapiGetter("userInfo", GetUserInfo),
478         NVal::DeclareNapiGetter("host", GetHost),
479         NVal::DeclareNapiGetter("port", GetPort),
480         NVal::DeclareNapiGetter("query", GetQuery),
481         NVal::DeclareNapiGetter("fragment", GetFragment),
482     };
483 
484     auto [succ, classValue] = NClass::DefineClass(exports_.env_, className, Constructor, std::move(props));
485     if (!succ) {
486         LOGE("Failed to define class");
487         NError(EIO).ThrowErr(exports_.env_);
488         return false;
489     }
490     succ = NClass::SaveClass(exports_.env_, className, classValue);
491     if (!succ) {
492         LOGE("Failed to save class");
493         NError(EIO).ThrowErr(exports_.env_);
494         return false;
495     }
496 
497     return exports_.AddProp(className, classValue);
498 }
499 
GetClassName()500 string FileUriNExporter::GetClassName()
501 {
502     return FileUriNExporter::className;
503 }
504 
FileUriNExporter(napi_env env,napi_value exports)505 FileUriNExporter::FileUriNExporter(napi_env env, napi_value exports) : NExporter(env, exports) {}
506 
~FileUriNExporter()507 FileUriNExporter::~FileUriNExporter() {}
508 } // namespace ModuleFileUri
509 } // namespace AppFileService
510 } // namespace OHOS
511