• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 package ohos;
17 
18 import java.io.File;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Locale;
22 
23 /**
24  * compress commend parser.
25  *
26  */
27 public class CompressVerify {
28     private static final String COMMA_SPLIT = ",";
29     private static final String JSON_PROFILE = "config.json";
30     private static final String MODULE_PROFILE = "module.json";
31     private static final String PROFILE_NAME = "CAPABILITY.profile";
32     private static final String INDEX_PROFILE = "resources.index";
33     private static final String RPCID_PROFILE = "rpcid.sc";
34     private static final String PACK_INFO = "pack.info";
35     private static final String PACK_RES = "pack.res";
36     private static final String HAP_SUFFIX = ".hap";
37     private static final String HAR_SUFFIX = ".har";
38     private static final String APP_SUFFIX = ".app";
39     private static final String APK_SUFFIX = ".apk";
40     private static final String DEX_SUFFIX = ".dex";
41     private static final String ABC_SUFFIX = ".abc";
42     private static final String SO_SUFFIX = ".so";
43     private static final String JAR_SUFFIX = ".jar";
44     private static final String TXT_SUFFIX = ".txt";
45     private static final String PNG_SUFFIX = ".png";
46     private static final String RES_SUFFIX = ".res";
47     private static final String ENTRY_CARD_DIRECTORY_NAME = "EntryCard";
48 
49     private static final Log LOG = new Log(CompressVerify.class.toString());
50 
51     private static final boolean TYPE_FILE = true;
52     private static final boolean TYPE_DIR = false;
53 
54     /**
55      * if args valid.
56      *
57      * @param utility common data
58      * @return commandVerify if command valid.
59      */
commandVerify(Utility utility)60     public static boolean commandVerify(Utility utility) {
61         if (utility == null) {
62             LOG.error("CompressVerify::commandVerify utility is null!");
63             return false;
64         }
65 
66         if (!utility.getForceRewrite().isEmpty() && !"true".equals(utility.getForceRewrite())
67                 && !"false".equals(utility.getForceRewrite())) {
68             LOG.error("CompressVerify::commandVerify forceRewrite is invalid!");
69             return false;
70         }
71         return commandPathVerify(utility);
72     }
73 
74     /**
75      * verify path.
76      *
77      * @param utility common data
78      * @return commandPathVerify if command valid.
79      */
commandPathVerify(Utility utility)80     private static boolean commandPathVerify(Utility utility) {
81         if (Utility.MODE_HAP.equals(utility.getMode())) {
82             if (!utility.getJsonPath().isEmpty()) {
83                 File file = new File(utility.getJsonPath());
84                 if (!file.isFile()) {
85                     LOG.error("CompressVerify::isArgsValidInHapMode json-path is not a file!");
86                     return false;
87                 }
88                 if (!file.getName().equals(JSON_PROFILE) && !file.getName().equals(MODULE_PROFILE)) {
89                     LOG.error("CompressVerify::isArgsValidInHapMode json-path must be config.json or module.json file!");
90                     return false;
91                 }
92             }
93 
94             if (!utility.getRpcidPath().isEmpty()) {
95                 File file = new File(utility.getRpcidPath());
96                 if (!file.isFile()) {
97                     LOG.error("CompressVerify::isArgsValidInHapMode rpcid-path is not a file!");
98                     return false;
99                 }
100                 if (!file.getName().equals(RPCID_PROFILE)) {
101                     LOG.error("CompressVerify::isArgsValidInHapMode rpcid-path must be rpcid.sc file!");
102                     return false;
103                 }
104             }
105 
106             if (!utility.getApkPath().isEmpty() && !compatibleProcess(utility, utility.getApkPath(),
107                     utility.getFormattedApkPathList(), APK_SUFFIX)) {
108                 LOG.error("CompressVerify::isArgsValidInHapMode shell-apk-path is invalid!");
109                 return false;
110             }
111 
112             if (!utility.getProfilePath().isEmpty()) {
113                 File file = new File(utility.getProfilePath());
114                 if (!file.isFile() || !file.getName().equals(PROFILE_NAME)) {
115                     LOG.error("CompressVerify::isArgsValidInHapMode profile-path must be CAPABILITY.profile file!");
116                     return false;
117                 }
118             }
119 
120             if (!utility.getDexPath().isEmpty() && !compatibleProcess(utility, utility.getDexPath(),
121                     utility.getFormattedDexPathList(), DEX_SUFFIX)) {
122                 LOG.error("CompressVerify::isArgsValidInHapMode dex-path is invalid!");
123                 return false;
124             }
125 
126             if (!utility.getAbcPath().isEmpty() && !compatibleProcess(utility, utility.getAbcPath(),
127                     utility.getFormattedAbcPathList(), ABC_SUFFIX)) {
128                 LOG.error("CompressVerify::isArgsValidInHapMode abc-path is invalid!");
129                 return false;
130             }
131 
132             return isVerifyValidInHapMode(utility);
133         } else if (Utility.MODE_HAR.equals(utility.getMode())) {
134             return isVerifyValidInHarMode(utility);
135         } else if (Utility.MODE_APP.equals(utility.getMode())) {
136             return isVerifyValidInAppMode(utility);
137         } else if (Utility.MODE_RES.equals(utility.getMode())) {
138             return isVerifyValidInResMode(utility);
139         } else {
140             LOG.error("CompressVerify::commandVerify mode is invalid!");
141             return false;
142         }
143     }
144 
145     /**
146      * parse and check args if valid in hap mode.
147      *
148      * @param utility common data
149      * @return isVerifyValidInHapMode if verify valid in hap mode.
150      */
isVerifyValidInHapMode(Utility utility)151     private static boolean isVerifyValidInHapMode(Utility utility) {
152         File file = new File(utility.getIndexPath());
153         if (!utility.getIndexPath().isEmpty() && !file.isFile() && file.getName().equals(INDEX_PROFILE)) {
154             LOG.error("CompressVerify::isArgsValidInHapMode index-path must be resources.index file!");
155             return false;
156         }
157 
158         if (!utility.getSoPath().isEmpty() &&
159                 !compatibleProcess(utility, utility.getSoPath(), utility.getFormattedSoPathList(), SO_SUFFIX)) {
160             LOG.error("CompressVerify::isArgsValidInHapMode maple-so-path is invalid!");
161             return false;
162         }
163 
164         if (!utility.getAbilitySoPath().isEmpty() && !compatibleProcess(utility, utility.getAbilitySoPath(),
165                 utility.getFormattedAbilitySoPathList(), SO_SUFFIX)) {
166             LOG.error("CompressVerify::isArgsValidInHapMode ability-so-path is invalid!");
167             return false;
168         }
169 
170         if (isHapPathValid(utility.getSoDir())) {
171             LOG.error("CompressVerify::isArgsValidInHapMode maple-so-dir is invalid!");
172             return false;
173         }
174 
175         if (isHapPathValid(utility.getLibPath())) {
176             LOG.error("CompressVerify::isArgsValidInHapMode lib-path is invalid!");
177             return false;
178         }
179 
180         if (isHapPathValid(utility.getResPath())) {
181             LOG.error("CompressVerify::isArgsValidInHapMode res-path is invalid!");
182             return false;
183         }
184 
185         if (isHapPathValid(utility.getResourcesPath())) {
186             LOG.error("CompressVerify::isArgsValidInHapMode resources-path is invalid!");
187             return false;
188         }
189 
190         if (isHapPathValid(utility.getAssetsPath())) {
191             LOG.error("CompressVerify::isArgsValidInHapMode assets-path is invalid!");
192             return false;
193         }
194 
195         if (isHapPathValid(utility.getSharedLibsPath())) {
196             LOG.error("CompressVerify::isArgsValidInHapMode shared-libs-path is invalid!");
197             return false;
198         }
199 
200         if (!utility.getJarPath().isEmpty()
201                 && !compatibleProcess(utility, utility.getJarPath(), utility.getFormattedJarPathList(), JAR_SUFFIX)) {
202             LOG.error("CompressVerify::isArgsValidInHapMode jar-path is invalid!");
203             return false;
204         }
205 
206         if (!utility.getTxtPath().isEmpty()
207                 && !compatibleProcess(utility, utility.getTxtPath(), utility.getFormattedTxtPathList(), TXT_SUFFIX)) {
208             LOG.error("CompressVerify::isArgsValidInHapMode txt-path is invalid!");
209             return false;
210         }
211 
212 
213         if (!utility.getPackInfoPath().isEmpty() && !isPathValid(utility.getPackInfoPath(), TYPE_FILE, PACK_INFO)) {
214             LOG.error("CompressVerify::isArgsValidInHapMode pack-info-path is invalid!");
215             return false;
216         }
217 
218         return isOutPathValid(utility, HAP_SUFFIX);
219     }
220 
221     /**
222      * check hap path if valid
223      *
224      * @param path path input
225      * @return isPathValid if path verify
226      */
isHapPathValid(String path)227     private static boolean isHapPathValid(String path) {
228         return (!path.isEmpty() && !isPathValid(path, TYPE_DIR, null));
229     }
230 
231     /**
232      * parse and check args if valid in har mode.
233      *
234      * @param utility common data
235      * @return isVerifyValidInHarMode if verify valid in har mode.
236      */
isVerifyValidInHarMode(Utility utility)237     private static boolean isVerifyValidInHarMode(Utility utility) {
238         if (utility.getJsonPath().isEmpty()) {
239             LOG.error("CompressVerify::isArgsValidInHarMode json-path is empty!");
240             return false;
241         }
242 
243         if (!isPathValid(utility.getJsonPath(), TYPE_FILE, JSON_PROFILE)
244             && !isPathValid(utility.getJsonPath(), TYPE_FILE, MODULE_PROFILE)) {
245             LOG.error("CompressVerify::isArgsValidInHarMode json-path must be config.json file!");
246             return false;
247         }
248 
249         if (!utility.getJarPath().isEmpty()
250                 && !compatibleProcess(utility, utility.getJarPath(), utility.getFormattedJarPathList(), JAR_SUFFIX)) {
251             LOG.error("CompressVerify::isArgsValidInHarMode jar-path is invalid!");
252             return false;
253         }
254 
255         if (!utility.getTxtPath().isEmpty()
256                 && !compatibleProcess(utility, utility.getTxtPath(), utility.getFormattedTxtPathList(), TXT_SUFFIX)) {
257             LOG.error("CompressVerify::isArgsValidInHarMode txt-path is invalid!");
258             return false;
259         }
260 
261         if (!utility.getLibPath().isEmpty() && !isPathValid(utility.getLibPath(), TYPE_DIR, null)) {
262             LOG.error("CompressVerify::isArgsValidInHarMode lib-path is invalid!");
263             return false;
264         }
265 
266         if (!utility.getResPath().isEmpty() && !isPathValid(utility.getResPath(), TYPE_DIR, null)) {
267             LOG.error("CompressVerify::isArgsValidInHarMode res-path is invalid!");
268             return false;
269         }
270 
271         if (utility.getResourcesPath().isEmpty() || !isPathValid(utility.getResourcesPath(), TYPE_DIR, null)) {
272             LOG.error("CompressVerify::isArgsValidInHarMode resources-path is invalid!");
273             return false;
274         }
275 
276         if (!utility.getAssetsPath().isEmpty() && !isPathValid(utility.getAssetsPath(), TYPE_DIR, null)) {
277             LOG.error("CompressVerify::isArgsValidInHarMode assets-path is invalid!");
278             return false;
279         }
280 
281         return isOutPathValid(utility, HAR_SUFFIX);
282     }
283 
284     /**
285      * parse and check args if valid in app mode.
286      *
287      * @param utility common data
288      * @return isVerifyValidInAppMode if verify valid in app mode.
289      */
isVerifyValidInAppMode(Utility utility)290     private static boolean isVerifyValidInAppMode(Utility utility) {
291         if (utility.getHapPath().isEmpty()) {
292             LOG.error("CompressVerify::isArgsValidInAppMode hap-path is empty!");
293             return false;
294         }
295 
296         if (!compatibleProcess(utility, utility.getHapPath(), utility.getFormattedHapPathList(), HAP_SUFFIX)) {
297             LOG.error("CompressVerify::isArgsValidInAppMode hap-path is invalid!");
298             return false;
299         }
300 
301         if (utility.getPackInfoPath().isEmpty()) {
302             LOG.error("CompressVerify::isArgsValidInAppMode pack-info-path is empty!");
303             return false;
304         }
305 
306         File file = new File(utility.getPackInfoPath());
307         if (!file.isFile() || !file.getName().equals(PACK_INFO)) {
308             LOG.error("CompressVerify::isArgsValidInAppMode pack-info-path is invalid!");
309             return false;
310         }
311 
312         if (!utility.getSignaturePath().isEmpty() && !(new File(utility.getSignaturePath())).isFile()) {
313             LOG.error("CompressVerify::isArgsValidInAppMode signature-path is invalid!");
314             return false;
315         }
316 
317         if (!utility.getCertificatePath().isEmpty() && !(new File(utility.getCertificatePath())).isFile()) {
318             LOG.error("CompressVerify::isArgsValidInAppMode certificate-path is invalid!");
319             return false;
320         }
321 
322         if (!utility.getEntryCardPath().isEmpty() &&
323                 !compatibleProcess(utility, utility.getEntryCardPath(),
324                         utility.getformattedEntryCardPathList(), PNG_SUFFIX)) {
325             LOG.error("CompressVerify::isArgsValidInAppMode entrycard-path is invalid!");
326             return false;
327         }
328         if (!utility.getPackResPath().isEmpty() && !isPathValid(utility.getPackResPath(), TYPE_FILE, PACK_RES)) {
329             LOG.error("CompressVerify::isArgsValidInAppMode pack-res-path is invalid!:" );
330             return false;
331         }
332 
333         return isOutPathValid(utility, APP_SUFFIX);
334     }
335 
336 
337     /**
338      * parse and check args if valid in res mode.
339      *
340      * @param utility common data
341      * @return isVerifyValidInAppMode if verify valid in app mode.
342      */
isVerifyValidInResMode(Utility utility)343     private static boolean isVerifyValidInResMode(Utility utility) {
344         if (!isPathValid(utility.getPackInfoPath(), TYPE_FILE, PACK_INFO)) {
345             LOG.error("CompressVerify::isArgsValidInResMode pack-info-path is invalid!");
346             return false;
347         }
348 
349         if (!isDirectoryValidStrictCase(utility.getEntryCardPath(), ENTRY_CARD_DIRECTORY_NAME)) {
350             LOG.error("CompressVerify::isArgsValidInResMode the level-1 directory name must is EntryCard" +
351                 ", current is " + utility.getEntryCardPath());
352             return false;
353         }
354         if (!compatibleProcess(utility, utility.getEntryCardPath(),
355                 utility.getformattedEntryCardPathList(), PNG_SUFFIX)) {
356             LOG.error("CompressVerify::isArgsValidInResMode entrycard-path is invalid!");
357             return false;
358         }
359         return isOutPathValid(utility, RES_SUFFIX);
360     }
361 
362 
363     /**
364      * Compatible file input and directory input
365      *
366      * @param utility   common data
367      * @param inputPath input path
368      * @param fileList  save files' path with list
369      * @param suffix    process type
370      * @return Returns {@code true} if the compatible is successful; returns {@code false} otherwise.
371      */
compatibleProcess(Utility utility, String inputPath, List<String> fileList, String suffix)372     private static boolean compatibleProcess(Utility utility, String inputPath,
373         List<String> fileList, String suffix) {
374         if (isPathValid(inputPath, TYPE_DIR, null)) {
375             File inputFile = new File(inputPath);
376             File[] files = inputFile.listFiles();
377             if (files == null) {
378                 return true;
379             }
380             for (File fileItem : files) {
381                 if (fileItem.getName().toLowerCase(Locale.ENGLISH).endsWith(suffix)) {
382                     fileList.add(fileItem.toString());
383                 }
384             }
385             return true;
386         } else {
387             String formattedPathItem = "";
388             List<String> pathList = removeDuplicatePath(inputPath);
389             for (String pathItem : pathList) {
390                 formattedPathItem = utility.getFormattedPath(pathItem);
391                 if (!isPathValid(formattedPathItem, TYPE_FILE, suffix)) {
392                     return false;
393                 }
394                 fileList.add(formattedPathItem);
395             }
396             return true;
397         }
398     }
399 
400     /**
401      * turn input path block to formatted path list
402      *
403      * @param utility common data
404      * @param suffix  used to determine type
405      * @return isVerifyValidInAppMode if verify valid in app mode.
406      */
isOutPathValid(Utility utility, String suffix)407     private static boolean isOutPathValid(Utility utility, String suffix) {
408         File outFile = new File(utility.getOutPath());
409 
410         if (("false".equals(utility.getForceRewrite())) && (outFile.exists())) {
411             LOG.error("CompressVerify::isOutPathValid out file already existed!");
412             return false;
413         }
414 
415         if (HAP_SUFFIX.equals(suffix)) {
416             if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX)) {
417                 LOG.error("CompressVerify::isOutPathValid out-path must end with .hap!");
418                 return false;
419             } else {
420                 return true;
421             }
422         }
423 
424         if (HAR_SUFFIX.equals(suffix)) {
425             if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(HAR_SUFFIX)) {
426                 LOG.error("CompressVerify::isOutPathValid out-path must end with .har!");
427                 return false;
428             } else {
429                 return true;
430             }
431         }
432 
433         if (APP_SUFFIX.equals(suffix)) {
434             if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(APP_SUFFIX)) {
435                 LOG.error("CompressVerify::isOutPathValid out-path must end with .app!");
436                 return false;
437             } else {
438                 return true;
439             }
440         }
441 
442         if (RES_SUFFIX.equals(suffix)) {
443             if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(RES_SUFFIX)) {
444                 LOG.error("CompressVerify::isOutPathValid out-path must end with .res!");
445                 return false;
446             } else {
447                 return true;
448             }
449         }
450 
451         return false;
452     }
453 
454     /**
455      * check path if valid
456      *
457      * @param path   path input
458      * @param isFile type input
459      * @param flag   flag input
460      * @return isPathValid if path verify
461      */
isPathValid(String path, boolean isFile, String flag)462     private static boolean isPathValid(String path, boolean isFile, String flag) {
463         File file = new File(path);
464         if (isFile && (file.isFile()) && file.getName().toLowerCase(Locale.ENGLISH).endsWith(flag)) {
465             return true;
466         }
467         return (!isFile) && file.isDirectory();
468     }
469 
isDirectoryValidStrictCase(String path, String directoryName)470     private static boolean isDirectoryValidStrictCase(String path, String directoryName) {
471         File file = new File(path);
472         if (!file.exists()) {
473             LOG.error("CompressVerify::isDirectoryValidStrictCase directory is not exist, directoryPath: "
474                 + path);
475             return false;
476         }
477         if (file.isDirectory()) {
478             return directoryName.equals(file.getName());
479         }
480         return false;
481     }
482 
483     /**
484      * remove duplicate in path.
485      *
486      * @param path input path, use comma separate.
487      * @return result list
488      */
removeDuplicatePath(String path)489     private static List<String> removeDuplicatePath(String path) {
490         String[] array = path.split(COMMA_SPLIT);
491         List<String> list = new ArrayList<>();
492 
493         for (String item : array) {
494             if (!list.contains(item)) {
495                 list.add(item);
496             }
497         }
498         return list;
499     }
500 }
501