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 com.alibaba.fastjson.JSONValidator; 19 import java.io.File; 20 import java.io.FileInputStream; 21 import java.io.FileReader; 22 import java.io.InputStreamReader; 23 import java.io.IOException; 24 import java.io.Reader; 25 import java.nio.charset.StandardCharsets; 26 import java.util.ArrayList; 27 import java.util.Locale; 28 import java.util.Map; 29 import java.util.regex.Matcher; 30 import java.util.regex.Pattern; 31 import java.util.List; 32 import java.util.Optional; 33 34 /** 35 * compress comment,command parser. 36 * 37 */ 38 public class CompressVerify { 39 private static final String COMMA_SPLIT = ","; 40 private static final String JSON_PROFILE = "config.json"; 41 private static final String MODULE_PROFILE = "module.json"; 42 private static final String PATCH_PROFILE = "patch.json"; 43 private static final String PKG_CONTEXT_INFO = "pkgContextInfo.json"; 44 private static final String PROFILE_NAME = "CAPABILITY.profile"; 45 private static final String INDEX_PROFILE = "resources.index"; 46 private static final String RPCID_PROFILE = "rpcid.sc"; 47 private static final String PACK_INFO = "pack.info"; 48 private static final String PACK_RES = "pack.res"; 49 private static final String HAP_SUFFIX = ".hap"; 50 private static final String HAR_SUFFIX = ".har"; 51 private static final String APP_SUFFIX = ".app"; 52 private static final String APK_SUFFIX = ".apk"; 53 private static final String DEX_SUFFIX = ".dex"; 54 private static final String ABC_SUFFIX = ".abc"; 55 private static final String SO_SUFFIX = ".so"; 56 private static final String JAR_SUFFIX = ".jar"; 57 private static final String TXT_SUFFIX = ".txt"; 58 private static final String PNG_SUFFIX = ".png"; 59 private static final String RES_SUFFIX = ".res"; 60 private static final String HQF_SUFFIX = ".hqf"; 61 private static final String APPQF_SUFFIX = ".appqf"; 62 private static final String HSP_SUFFIX = ".hsp"; 63 private static final String JSON_SUFFIX = ".json"; 64 private static final String FALSE = "false"; 65 private static final String ENTRY_CARD_DIRECTORY_NAME = "EntryCard"; 66 private static final String VERSION_NAME_PATTERN = "^[0-9.]+|(?=.*[{])(?=.*[}])[0-9a-zA-Z_.{}]+$"; 67 private static final String LINUX_FILE_SEPARATOR = "/"; 68 private static final String BUNDLE_TYPE_SHARE = "shared"; 69 private static final String BUNDLE_TYPE_APP = "app"; 70 private static final String BUNDLE_TYPE_APP_SERVICE = "appService"; 71 private static final String SKILLS_ENTITIES = "entities"; 72 private static final String SKILLS_ACTIONS = "actions"; 73 private static final String ACTION_SYSTEM_HOME = "action.system.home"; 74 private static final String ENTITY_SYSTEM_HOME = "entity.system.home"; 75 private static final String BUNDLE_NAME_PATTERN = 76 "([a-zA-Z]|[a-zA-Z]+(_*[0-9a-zA-Z])+)(\\.[0-9a-zA-Z]|\\.[0-9a-zA-Z]+(_*[0-9a-zA-Z])+){2,}"; 77 private static final int BUNDLE_NAME_LEN_MIN = 7; 78 private static final int BUNDLE_NAME_LEN_MAX = 128; 79 80 private static final Log LOG = new Log(CompressVerify.class.toString()); 81 82 private static final boolean TYPE_FILE = true; 83 private static final boolean TYPE_DIR = false; 84 private static final Integer ONE = 1; 85 86 /** 87 * if args valid. 88 * 89 * @param utility common data 90 * @return commandVerify if command valid. 91 */ commandVerify(Utility utility)92 public static boolean commandVerify(Utility utility) { 93 if (utility == null) { 94 LOG.error(PackingToolErrMsg.COMMAND_VERIFY_FAILED.toString("Command verify utility is null.")); 95 return false; 96 } 97 98 if (!utility.getForceRewrite().isEmpty() && !"true".equals(utility.getForceRewrite()) 99 && !"false".equals(utility.getForceRewrite())) { 100 LOG.error(PackingToolErrMsg.COMMAND_VERIFY_FAILED.toString( 101 "If the --force parameter is configured, the value must be either 'true' or 'false'.")); 102 return false; 103 } 104 return commandPathVerify(utility); 105 } 106 107 /** 108 * verify path. 109 * 110 * @param utility common data 111 * @return commandPathVerify if command valid. 112 */ commandPathVerify(Utility utility)113 private static boolean commandPathVerify(Utility utility) { 114 switch (utility.getMode()) { 115 case Utility.MODE_HAP: 116 if (!utility.getBinPath().isEmpty() && utility.getJsonPath().isEmpty()) { 117 return isOutPathValid(utility, HAP_SUFFIX); 118 } else { 119 return isVerifyValidInHapCommonMode(utility) && isVerifyValidInHapMode(utility); 120 } 121 case Utility.MODE_HAR: 122 return isVerifyValidInHarMode(utility); 123 case Utility.MODE_APP: 124 return isVerifyValidInAppMode(utility); 125 case Utility.MODE_FAST_APP: 126 return PackageUtil.isVerifyValidInFastAppMode(utility); 127 case Utility.MODE_RES: 128 return isVerifyValidInResMode(utility); 129 case Utility.MODE_MULTI_APP: 130 return isVerifyValidInMultiAppMode(utility); 131 case Utility.MODE_HQF: 132 return isVerifyValidInHQFMode(utility); 133 case Utility.MODE_APPQF: 134 return isVerifyValidInAPPQFMode(utility); 135 case Utility.MODE_HSP: 136 return isVerifyValidInHspMode(utility); 137 case Utility.MODE_HAPADDITION: 138 return isVerifyValidInHapAdditionMode(utility); 139 case Utility.VERSION_NORMALIZE: 140 return validateVersionNormalizeMode(utility); 141 case Utility.PACKAGE_NORMALIZE: 142 return validatePackageNormalizeMode(utility); 143 default: 144 LOG.error(PackingToolErrMsg.COMMAND_MODE_INVALID.toString()); 145 return false; 146 } 147 } 148 isBundleNameValid(String bundleName)149 private static boolean isBundleNameValid(String bundleName) { 150 if (bundleName != null && 151 bundleName.length() >= BUNDLE_NAME_LEN_MIN && 152 bundleName.length() <= BUNDLE_NAME_LEN_MAX) { 153 Pattern pattern = Pattern.compile(BUNDLE_NAME_PATTERN); 154 return pattern.matcher(bundleName).matches(); 155 } 156 return false; 157 } 158 validatePackageNormalizeMode(Utility utility)159 private static boolean validatePackageNormalizeMode(Utility utility) { 160 if (utility.getHspList().isEmpty()) { 161 LOG.error("CompressVerify::validatePackageNormalizeMode hsp-list is empty."); 162 return false; 163 } else { 164 if (!compatibleProcess(utility, utility.getHspList(), utility.getFormattedHspPathList(), HSP_SUFFIX)) { 165 LOG.error("CompressVerify::validatePackageNormalizeMode hsp-list is invalid."); 166 return false; 167 } 168 } 169 if (!isBundleNameValid(utility.getBundleName())) { 170 LOG.error("CompressVerify::validatePackageNormalizeMode bundle-name is invalid."); 171 return false; 172 } 173 if (utility.getVersionCode() <= 0) { 174 LOG.error("CompressVerify::validatePackageNormalizeMode version-code is invalid."); 175 return false; 176 } 177 if (utility.getOutPath().isEmpty()) { 178 LOG.error("CompressVerify::validatePackageNormalizeMode out-path is empty."); 179 return false; 180 } 181 File outDir = new File(utility.getOutPath()); 182 if (!outDir.isDirectory()) { 183 LOG.error("CompressVerify::validatePackageNormalizeMode out-path is not a directory."); 184 return false; 185 } 186 return true; 187 } 188 validateVersionNormalizeMode(Utility utility)189 private static boolean validateVersionNormalizeMode(Utility utility) { 190 if (utility.getInputList().isEmpty()) { 191 LOG.error("CompressVerify::validateVersionNormalizeMode input-list is empty."); 192 return false; 193 } 194 195 if (!handleHapAndHspInput(utility, utility.getInputList(), utility.getFormattedHapList())) { 196 LOG.error("CompressVerify::validateVersionNormalizeMode input-list is invalid."); 197 return false; 198 } 199 200 if (utility.getFormattedHapList().isEmpty()) { 201 LOG.error("CompressVerify::validateVersionNormalizeMode input-list is empty."); 202 return false; 203 } 204 205 if (utility.getVersionCode() <= 0) { 206 LOG.error("CompressVerify::validateVersionNormalizeMode version-code is invalid."); 207 return false; 208 } 209 210 if (utility.getVersionName().isEmpty()) { 211 LOG.error("CompressVerify::validateVersionNormalizeMode version-name is empty."); 212 return false; 213 } 214 215 Pattern versionNamePattern = Pattern.compile(VERSION_NAME_PATTERN); 216 Matcher versionNameMatcher = versionNamePattern.matcher(utility.getVersionName()); 217 if (!versionNameMatcher.matches()) { 218 LOG.error("CompressVerify::validateVersionNormalizeMode version-name is not valid."); 219 return false; 220 } 221 222 if (utility.getOutPath().isEmpty()) { 223 LOG.error("CompressVerify::validateVersionNormalizeMode out-path is empty."); 224 return false; 225 } 226 227 File outDir = new File(utility.getOutPath()); 228 if (!outDir.isDirectory()) { 229 LOG.error("CompressVerify::validateVersionNormalizeMode out-path is not a directory."); 230 return false; 231 } 232 return true; 233 } 234 isValidRpcid(Utility utility)235 private static boolean isValidRpcid(Utility utility) { 236 if (!utility.getRpcidPath().isEmpty()) { 237 File file = new File(utility.getRpcidPath()); 238 if (!file.isFile()) { 239 String errMsg = "--rpcid-path is not a file."; 240 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 241 return false; 242 } 243 if (!RPCID_PROFILE.equals(file.getName())) { 244 String errMsg = "--rpcid-path must be the rpcid.sc file."; 245 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 246 return false; 247 } 248 } 249 return true; 250 } 251 isValidPackInfo(Utility utility)252 private static boolean isValidPackInfo(Utility utility) { 253 if (!utility.getPackInfoPath().isEmpty()) { 254 File file = new File(utility.getPackInfoPath()); 255 if (!file.isFile()) { 256 String errMsg = "--pack-info-path is not a file."; 257 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 258 return false; 259 } 260 if (!PACK_INFO.equals(file.getName())) { 261 String errMsg = "--pack-info-path must be the pack.info file."; 262 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 263 return false; 264 } 265 } 266 return true; 267 } 268 isVerifyValidInHapCommonMode(Utility utility)269 private static boolean isVerifyValidInHapCommonMode(Utility utility) { 270 if (utility.getJsonPath().isEmpty()) { 271 String errMsg = "--json-path is empty"; 272 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 273 return false; 274 } 275 if (!isPathValid(utility.getJsonPath(), TYPE_FILE, JSON_PROFILE) 276 && !isPathValid(utility.getJsonPath(), TYPE_FILE, MODULE_PROFILE)) { 277 String errMsg = "--json-path must be the config.json file or module.json file."; 278 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 279 return false; 280 } 281 282 if (!isValidRpcid(utility) || !isValidPackInfo(utility)) { 283 return false; 284 } 285 286 if (!utility.getApkPath().isEmpty() && !compatibleProcess(utility, utility.getApkPath(), 287 utility.getFormattedApkPathList(), APK_SUFFIX)) { 288 String errMsg = "--shell-apk-path is invalid."; 289 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 290 return false; 291 } 292 293 if (!utility.getProfilePath().isEmpty()) { 294 File file = new File(utility.getProfilePath()); 295 if (!file.isFile() || !PROFILE_NAME.equals(file.getName())) { 296 String errMsg = "--profile-path must be the CAPABILITY.profile file."; 297 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 298 return false; 299 } 300 } 301 302 if (!utility.getDexPath().isEmpty() && !compatibleProcess(utility, utility.getDexPath(), 303 utility.getFormattedDexPathList(), DEX_SUFFIX)) { 304 String errMsg = "--dex-path is invalid."; 305 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 306 return false; 307 } 308 309 if (!utility.getAbcPath().isEmpty() && !compatibleProcess(utility, utility.getAbcPath(), 310 utility.getFormattedAbcPathList(), ABC_SUFFIX)) { 311 String errMsg = "--abc-path is invalid."; 312 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 313 return false; 314 } 315 316 if (!utility.getDirList().isEmpty() && !splitDirList(utility, utility.getDirList(), 317 utility.getFormatedDirList())) { 318 String errMsg = "--dir-list is invalid."; 319 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 320 return false; 321 } 322 if (!utility.getPkgContextPath().isEmpty()) { 323 File file = new File(utility.getPkgContextPath()); 324 if (!file.isFile() || !PKG_CONTEXT_INFO.equals(file.getName())) { 325 String errMsg = "--pkg-context-path file must be the pkgContextInfo.json file."; 326 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 327 return false; 328 } 329 } 330 return true; 331 } 332 333 /** 334 * parse and check args if valid in hap mode. 335 * 336 * @param utility common data 337 * @return isVerifyValidInHapMode if verify valid in hap mode. 338 */ isVerifyValidInHapMode(Utility utility)339 private static boolean isVerifyValidInHapMode(Utility utility) { 340 File file = new File(utility.getIndexPath()); 341 if (!utility.getIndexPath().isEmpty() && !file.isFile() && INDEX_PROFILE.equals(file.getName())) { 342 String errMsg = "--index-path must be the resources.index file."; 343 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 344 return false; 345 } 346 347 if (!utility.getSoPath().isEmpty() && 348 !compatibleProcess(utility, utility.getSoPath(), utility.getFormattedSoPathList(), SO_SUFFIX)) { 349 String errMsg = "--maple-so-path is invalid."; 350 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 351 return false; 352 } 353 354 if (!utility.getAbilitySoPath().isEmpty() && !compatibleProcess(utility, utility.getAbilitySoPath(), 355 utility.getFormattedAbilitySoPathList(), SO_SUFFIX)) { 356 String errMsg = "--ability-so-path is invalid."; 357 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 358 return false; 359 } 360 361 if (isHapPathValid(utility.getSoDir())) { 362 String errMsg = "--maple-so-dir is invalid."; 363 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 364 return false; 365 } 366 367 if (isHapPathValid(utility.getLibPath())) { 368 String errMsg = "--lib-path is invalid."; 369 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 370 return false; 371 } 372 373 if (isHapPathValid(utility.getHnpPath())) { 374 String errMsg = "--hnp-path is invalid."; 375 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 376 return false; 377 } 378 379 if (isHapPathValid(utility.getResPath())) { 380 String errMsg = "--res-path is invalid."; 381 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 382 return false; 383 } 384 385 if (isHapPathValid(utility.getResourcesPath())) { 386 String errMsg = "--resources-path is invalid."; 387 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 388 return false; 389 } 390 391 if (isHapPathValid(utility.getAssetsPath())) { 392 String errMsg = "--assets-path is invalid."; 393 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 394 return false; 395 } 396 397 if (isHapPathValid(utility.getSharedLibsPath())) { 398 String errMsg = "--shared-libs-path is invalid."; 399 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 400 return false; 401 } 402 403 if (!utility.getJarPath().isEmpty() 404 && !compatibleProcess(utility, utility.getJarPath(), utility.getFormattedJarPathList(), JAR_SUFFIX)) { 405 String errMsg = "--jar-path is invalid."; 406 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 407 return false; 408 } 409 410 if (!utility.getTxtPath().isEmpty() 411 && !compatibleProcess(utility, utility.getTxtPath(), utility.getFormattedTxtPathList(), TXT_SUFFIX)) { 412 String errMsg = "--txt-path is invalid."; 413 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 414 return false; 415 } 416 417 if (isHapPathValid(utility.getANPath())) { 418 String errMsg = "--an-path is invalid."; 419 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 420 return false; 421 } 422 423 if (!utility.getEtsPath().isEmpty() && !isPathExists(utility.getEtsPath())) { 424 String errMsg = "--ets-path is invalid."; 425 LOG.error(PackingToolErrMsg.HAP_MODE_ARGS_INVALID.toString(errMsg)); 426 return false; 427 } 428 429 return isOutPathValid(utility, HAP_SUFFIX); 430 } 431 432 /** 433 * check hap path if valid 434 * 435 * @param path path input 436 * @return isPathValid if path verify 437 */ isHapPathValid(String path)438 private static boolean isHapPathValid(String path) { 439 return (!path.isEmpty() && !isPathValid(path, TYPE_DIR, null)); 440 } 441 442 /** 443 * parse and check args if valid in har mode. 444 * 445 * @param utility common data 446 * @return isVerifyValidInHarMode if verify valid in har mode. 447 */ isVerifyValidInHarMode(Utility utility)448 private static boolean isVerifyValidInHarMode(Utility utility) { 449 if (utility.getJsonPath().isEmpty()) { 450 LOG.error("CompressVerify::isArgsValidInHarMode json-path is empty."); 451 return false; 452 } 453 454 if (!isPathValid(utility.getJsonPath(), TYPE_FILE, JSON_PROFILE) 455 && !isPathValid(utility.getJsonPath(), TYPE_FILE, MODULE_PROFILE)) { 456 LOG.error("CompressVerify::isArgsValidInHarMode json-path must be config.json file."); 457 return false; 458 } 459 460 if (!utility.getJarPath().isEmpty() 461 && !compatibleProcess(utility, utility.getJarPath(), utility.getFormattedJarPathList(), JAR_SUFFIX)) { 462 LOG.error("CompressVerify::isArgsValidInHarMode jar-path is invalid."); 463 return false; 464 } 465 466 if (!utility.getTxtPath().isEmpty() 467 && !compatibleProcess(utility, utility.getTxtPath(), utility.getFormattedTxtPathList(), TXT_SUFFIX)) { 468 LOG.error("CompressVerify::isArgsValidInHarMode txt-path is invalid."); 469 return false; 470 } 471 472 if (!utility.getLibPath().isEmpty() && !isPathValid(utility.getLibPath(), TYPE_DIR, null)) { 473 LOG.error("CompressVerify::isArgsValidInHarMode lib-path is invalid."); 474 return false; 475 } 476 477 if (!utility.getResPath().isEmpty() && !isPathValid(utility.getResPath(), TYPE_DIR, null)) { 478 LOG.error("CompressVerify::isArgsValidInHarMode res-path is invalid."); 479 return false; 480 } 481 482 if (utility.getResourcesPath().isEmpty() || !isPathValid(utility.getResourcesPath(), TYPE_DIR, null)) { 483 LOG.error("CompressVerify::isArgsValidInHarMode resources-path is invalid."); 484 return false; 485 } 486 487 if (!utility.getAssetsPath().isEmpty() && !isPathValid(utility.getAssetsPath(), TYPE_DIR, null)) { 488 LOG.error("CompressVerify::isArgsValidInHarMode assets-path is invalid."); 489 return false; 490 } 491 492 return isOutPathValid(utility, HAR_SUFFIX); 493 } 494 495 /** 496 * parse and check args if valid in app mode. 497 * 498 * @param utility common data 499 * @return isVerifyValidInAppMode if verify valid in app mode. 500 */ isVerifyValidInAppMode(Utility utility)501 private static boolean isVerifyValidInAppMode(Utility utility) { 502 if (!checkBundleTypeConsistency(utility)) { 503 String errMsg = "The bundleType is inconsistent for different HAP and HSP modules."; 504 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 505 return false; 506 } 507 508 if (!checkInputModulePath(utility)) { 509 LOG.warning("CompressVerify::isArgsValidInAppMode input hap-path or hspPath is invalid."); 510 } 511 512 if (!utility.getHapPath().isEmpty() 513 && !compatibleProcess(utility, utility.getHapPath(), utility.getFormattedHapPathList(), HAP_SUFFIX)) { 514 String errMsg = "--hap-path is invalid."; 515 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 516 return false; 517 } 518 519 if (!utility.getHspPath().isEmpty() 520 && !compatibleProcess(utility, utility.getHspPath(), utility.getFormattedHspPathList(), HSP_SUFFIX)) { 521 String errMsg = "--hsp-path is invalid."; 522 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 523 return false; 524 } 525 526 if (utility.getPackInfoPath().isEmpty()) { 527 String errMsg = "--pack-info-path is empty."; 528 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 529 return false; 530 } 531 532 File file = new File(utility.getPackInfoPath()); 533 if (!file.isFile() || !PACK_INFO.equals(file.getName())) { 534 String errMsg = "--pack-info-path is invalid."; 535 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 536 return false; 537 } 538 539 if (!isValidEncryptJsonFile(utility)) { 540 String errMsg = "--encrypt-path is invalid."; 541 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 542 return false; 543 } 544 545 if (!utility.getSignaturePath().isEmpty() && !(new File(utility.getSignaturePath())).isFile()) { 546 String errMsg = "--signature-path is invalid."; 547 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 548 return false; 549 } 550 551 if (!utility.getCertificatePath().isEmpty() && !(new File(utility.getCertificatePath())).isFile()) { 552 String errMsg = "--certificate-path is invalid."; 553 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 554 return false; 555 } 556 557 if (!utility.getEntryCardPath().isEmpty() && 558 !compatibleProcess(utility, utility.getEntryCardPath(), 559 utility.getformattedEntryCardPathList(), PNG_SUFFIX)) { 560 String errMsg = "--entrycard-path is invalid."; 561 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 562 return false; 563 } 564 if (!utility.getPackResPath().isEmpty() && !isPathValid(utility.getPackResPath(), TYPE_FILE, PACK_RES)) { 565 String errMsg = "--pack-res-path is invalid."; 566 LOG.error(PackingToolErrMsg.APP_MODE_ARGS_INVALID.toString(errMsg)); 567 return false; 568 } 569 570 return isOutPathValid(utility, APP_SUFFIX); 571 } 572 checkBundleTypeConsistency(Utility utility)573 private static boolean checkBundleTypeConsistency(Utility utility) { 574 String bundleType = new String(); 575 List<String> tmpHapPathList = new ArrayList<>(); 576 List<String> tmpHspPathList = new ArrayList<>(); 577 compatibleProcess(utility, utility.getHapPath(), tmpHapPathList, HAP_SUFFIX); 578 compatibleProcess(utility, utility.getHspPath(), tmpHspPathList, HSP_SUFFIX); 579 try { 580 if (!tmpHapPathList.isEmpty()) { 581 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(tmpHapPathList.get(0)); 582 bundleType = hapVerifyInfo.getBundleType(); 583 } else if (!tmpHspPathList.isEmpty()) { 584 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(tmpHspPathList.get(0)); 585 bundleType = hapVerifyInfo.getBundleType(); 586 } 587 for (String hapPath : tmpHapPathList) { 588 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(hapPath); 589 if (!bundleType.equals(hapVerifyInfo.getBundleType())) { 590 LOG.error(PackingToolErrMsg.CHECK_BUNDLETYPE_CONSISTENCY_FAILED.toString( 591 "The bundleType is not same for different HAP modules.")); 592 return false; 593 } 594 } 595 for (String hspPath : tmpHspPathList) { 596 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(hspPath); 597 if (!bundleType.equals(hapVerifyInfo.getBundleType())) { 598 LOG.error(PackingToolErrMsg.CHECK_BUNDLETYPE_CONSISTENCY_FAILED.toString( 599 "The bundleType is not same for different HSP modules.")); 600 return false; 601 } 602 } 603 } catch (BundleException e) { 604 return true; 605 } 606 return true; 607 } 608 checkInputModulePath(Utility utility)609 private static boolean checkInputModulePath(Utility utility) { 610 boolean isSharedApp = isSharedApp(utility); 611 boolean isAppService = isAppService(utility); 612 if (utility.getHapPath().isEmpty() && !isSharedApp && !isAppService) { 613 LOG.warning("CompressVerify::CheckInputModulePath hap-path is empty."); 614 return false; 615 } 616 617 if (utility.getHspPath().isEmpty() && isAppService) { 618 LOG.warning("CompressVerify::CheckInputModulePath hsp-path is empty."); 619 return false; 620 } 621 return true; 622 } 623 624 /** 625 * parse and check args if valid in multiApp mode. 626 * 627 * @param utility common data 628 * @return isVerifyValidInMultiAppMode if verify valid in multiApp mode. 629 */ isVerifyValidInMultiAppMode(Utility utility)630 private static boolean isVerifyValidInMultiAppMode(Utility utility) { 631 if (utility.getAppList().isEmpty() && utility.getHapList().isEmpty() && utility.getHspList().isEmpty()) { 632 LOG.error("CompressVerify::isVerifyValidInMultiAppMode input app-list, hap-list and hsp-list are null."); 633 return false; 634 } 635 if (!utility.getAppList().isEmpty()) { 636 if (!compatibleProcess(utility, utility.getAppList(), utility.getFormattedAppList(), APP_SUFFIX)) { 637 LOG.error("CompressVerify::isVerifyValidInMultiAppMode app-list is invalid."); 638 return false; 639 } 640 } 641 if (!utility.getHapList().isEmpty()) { 642 if (!compatibleProcess(utility, utility.getHapList(), utility.getFormattedHapList(), HAP_SUFFIX)) { 643 LOG.error("CompressVerify::isVerifyValidInMultiAppMode hap-list is invalid."); 644 return false; 645 } 646 } 647 648 if (!utility.getHspList().isEmpty()) { 649 if (!compatibleProcess(utility, utility.getHspList(), utility.getFormattedHapList(), HSP_SUFFIX)) { 650 LOG.error("CompressVerify::isVerifyValidInMultiAppMode hsp-list is invalid."); 651 return false; 652 } 653 } 654 655 if (!isValidEncryptJsonFile(utility)) { 656 LOG.error("CompressVerify::isVerifyValidInMultiAppMode encrypt-path is invalid."); 657 return false; 658 } 659 660 File outFile = new File(utility.getOutPath()); 661 if (("false".equals(utility.getForceRewrite())) && outFile.exists()) { 662 LOG.error("CompressVerify::isVerifyValidInMultiAppMode out file already existed."); 663 return false; 664 } 665 if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(APP_SUFFIX)) { 666 LOG.error("CompressVerify::isVerifyValidInMultiAppMode out-path must end with .app."); 667 return false; 668 } 669 return true; 670 } 671 672 673 /** 674 * parse and check args if valid in res mode. 675 * 676 * @param utility common data 677 * @return isVerifyValidInAppMode if verify valid in app mode. 678 */ isVerifyValidInResMode(Utility utility)679 private static boolean isVerifyValidInResMode(Utility utility) { 680 if (!isPathValid(utility.getPackInfoPath(), TYPE_FILE, PACK_INFO)) { 681 LOG.error("CompressVerify::isArgsValidInResMode pack-info-path is invalid."); 682 return false; 683 } 684 685 if (!isDirectoryValidStrictCase(utility.getEntryCardPath(), ENTRY_CARD_DIRECTORY_NAME)) { 686 LOG.error("CompressVerify::isArgsValidInResMode the level-1 directory name must is EntryCard" + 687 ", current is " + utility.getEntryCardPath()); 688 return false; 689 } 690 if (!compatibleProcess(utility, utility.getEntryCardPath(), 691 utility.getformattedEntryCardPathList(), PNG_SUFFIX)) { 692 LOG.error("CompressVerify::isArgsValidInResMode entrycard-path is invalid."); 693 return false; 694 } 695 return isOutPathValid(utility, RES_SUFFIX); 696 } 697 isVerifyValidInHQFMode(Utility utility)698 private static boolean isVerifyValidInHQFMode(Utility utility) { 699 if (utility.getJsonPath().isEmpty()) { 700 LOG.error("must input patch.json file when pack hqf file."); 701 return false; 702 } 703 if (!utility.getEtsPath().isEmpty()) { 704 if (!isPathValid(utility.getEtsPath(), TYPE_DIR, null)) { 705 LOG.error("must input valid ets path when pack hqf file."); 706 return false; 707 } 708 } 709 if (!isPathValid(utility.getJsonPath(), TYPE_FILE, PATCH_PROFILE)) { 710 LOG.error("input patch.json is invalid when pack hqf file."); 711 return false; 712 } 713 if (!utility.getLibPath().isEmpty()) { 714 if (!isPathValid(utility.getLibPath(), TYPE_DIR, null)) { 715 LOG.error("input lib path is invalid when pack hqf file."); 716 return false; 717 } 718 } 719 if (!utility.getResourcesPath().isEmpty()) { 720 if (!isPathValid(utility.getResourcesPath(), TYPE_DIR, null)) { 721 LOG.error("input resources path is invalid when pack hqf file."); 722 return false; 723 } 724 } 725 File outFile = new File(utility.getOutPath()); 726 if ((FALSE.equals(utility.getForceRewrite())) && (outFile.exists())) { 727 LOG.error(outFile.getName() + " already exist."); 728 return false; 729 } 730 if (!utility.getOutPath().endsWith(HQF_SUFFIX)) { 731 LOG.error("input out file must end with .hqf."); 732 return false; 733 } 734 return true; 735 } 736 isVerifyValidInAPPQFMode(Utility utility)737 private static boolean isVerifyValidInAPPQFMode(Utility utility) { 738 if (utility.getHqfList().isEmpty()) { 739 LOG.error("input hqf list is empty."); 740 return false; 741 } 742 if (!compatibleProcess(utility, utility.getHqfList(), utility.getFormatedHQFList(), HQF_SUFFIX)) { 743 LOG.error("input hqf list is invalid."); 744 return false; 745 } 746 File outFile = new File(utility.getOutPath()); 747 if ((FALSE.equals(utility.getForceRewrite())) && outFile.exists()) { 748 LOG.error("Error out file already existed."); 749 return false; 750 } 751 if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(APPQF_SUFFIX)) { 752 LOG.error("Error out-path must end with .app."); 753 return false; 754 } 755 return true; 756 } 757 758 /** 759 * Compatible file input and directory input 760 * 761 * @param utility common data 762 * @param inputPath input path 763 * @param fileList save files' path with list 764 * @param suffix process type 765 * @return Returns {@code true} if the compatible is successful; returns {@code false} otherwise. 766 */ compatibleProcess(Utility utility, String inputPath, List<String> fileList, String suffix)767 public static boolean compatibleProcess(Utility utility, String inputPath, 768 List<String> fileList, String suffix) { 769 if (isPathValid(inputPath, TYPE_DIR, null)) { 770 File inputFile = new File(inputPath); 771 File[] files = inputFile.listFiles(); 772 if (files == null) { 773 return true; 774 } 775 for (File fileItem : files) { 776 if (fileItem.getName().toLowerCase(Locale.ENGLISH).endsWith(suffix)) { 777 fileList.add(fileItem.toString()); 778 } 779 } 780 return true; 781 } else { 782 String formattedPathItem = ""; 783 List<String> pathList = removeDuplicatePath(inputPath); 784 for (String pathItem : pathList) { 785 formattedPathItem = utility.getFormattedPath(pathItem); 786 if (!isPathValid(formattedPathItem, TYPE_FILE, suffix)) { 787 return false; 788 } 789 fileList.add(formattedPathItem); 790 } 791 return true; 792 } 793 } 794 handleHapAndHspInput(Utility utility, String inputPath, List<String> fileList)795 private static boolean handleHapAndHspInput(Utility utility, String inputPath, List<String> fileList) { 796 if (isPathValid(inputPath, TYPE_DIR, null)) { 797 File inputFile = new File(inputPath); 798 File[] files = inputFile.listFiles(); 799 if (files == null) { 800 return true; 801 } 802 for (File fileItem : files) { 803 if (fileItem.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX) || 804 fileItem.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX)) { 805 fileList.add(fileItem.toString()); 806 } 807 } 808 return true; 809 } else { 810 String formattedPathItem = ""; 811 List<String> pathList = removeDuplicatePath(inputPath); 812 for (String pathItem : pathList) { 813 formattedPathItem = utility.getFormattedPath(pathItem); 814 if (!isPathValid(formattedPathItem, TYPE_FILE, HSP_SUFFIX) && 815 !isPathValid(formattedPathItem, TYPE_FILE, HAP_SUFFIX)) { 816 LOG.error("input file " + formattedPathItem + " not valid"); 817 return false; 818 } 819 fileList.add(formattedPathItem); 820 } 821 return true; 822 } 823 } 824 splitDirList(Utility utility, String dirList, List<String> fileList)825 private static boolean splitDirList(Utility utility, String dirList, List<String> fileList) { 826 List<String> pathList = removeDuplicatePath(dirList); 827 for (String pathItem : pathList) { 828 String formattedPathItem = utility.getFormattedPath(pathItem); 829 if (!isPathValid(formattedPathItem, TYPE_DIR, null)) { 830 return false; 831 } 832 fileList.add(formattedPathItem); 833 } 834 return true; 835 } 836 837 /** 838 * turn input path block to formatted path list 839 * 840 * @param utility common data 841 * @param suffix used to determine type 842 * @return isVerifyValidInAppMode if verify valid in app mode. 843 */ isOutPathValid(Utility utility, String suffix)844 private static boolean isOutPathValid(Utility utility, String suffix) { 845 File outFile = new File(utility.getOutPath()); 846 847 if (("false".equals(utility.getForceRewrite())) && (outFile.exists())) { 848 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path file already existed.")); 849 return false; 850 } 851 852 if (HAP_SUFFIX.equals(suffix)) { 853 if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX)) { 854 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .hap.")); 855 return false; 856 } else { 857 return true; 858 } 859 } 860 861 if (HAR_SUFFIX.equals(suffix)) { 862 if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(HAR_SUFFIX)) { 863 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .har.")); 864 return false; 865 } else { 866 return true; 867 } 868 } 869 870 if (APP_SUFFIX.equals(suffix)) { 871 if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(APP_SUFFIX)) { 872 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .app.")); 873 return false; 874 } else { 875 return true; 876 } 877 } 878 879 if (RES_SUFFIX.equals(suffix)) { 880 if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(RES_SUFFIX)) { 881 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .res.")); 882 return false; 883 } else { 884 return true; 885 } 886 } 887 888 if (HSP_SUFFIX.equals(suffix)) { 889 if (!outFile.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) { 890 LOG.error(PackingToolErrMsg.OUT_PATH_INVALID.toString("--out-path must end with .hsp.")); 891 return false; 892 } else { 893 return true; 894 } 895 } 896 return false; 897 } 898 899 /** 900 * check path if valid 901 * 902 * @param path path input 903 * @param isFile type input 904 * @param flag flag input 905 * @return isPathValid if path verify 906 */ isPathValid(String path, boolean isFile, String flag)907 private static boolean isPathValid(String path, boolean isFile, String flag) { 908 File file = new File(path); 909 if (isFile && (file.isFile()) && file.getName().toLowerCase(Locale.ENGLISH).endsWith(flag)) { 910 return true; 911 } 912 return (!isFile) && file.isDirectory(); 913 } 914 isPathExists(String path)915 private static boolean isPathExists(String path) { 916 if (path != null && !path.isEmpty()) { 917 File filePath = new File(path); 918 return filePath.exists(); 919 } 920 return false; 921 } 922 isDirectoryValidStrictCase(String path, String directoryName)923 private static boolean isDirectoryValidStrictCase(String path, String directoryName) { 924 File file = new File(path); 925 if (!file.exists()) { 926 LOG.error("CompressVerify::isDirectoryValidStrictCase directory is not exist, directoryPath: " 927 + path + "."); 928 return false; 929 } 930 if (file.isDirectory()) { 931 return directoryName.equals(file.getName()); 932 } 933 return false; 934 } 935 936 /** 937 * remove duplicate in path. 938 * 939 * @param path input path, use comma separate. 940 * @return result list 941 */ removeDuplicatePath(String path)942 private static List<String> removeDuplicatePath(String path) { 943 String[] array = path.split(COMMA_SPLIT); 944 List<String> list = new ArrayList<>(); 945 946 for (String item : array) { 947 if (!list.contains(item)) { 948 list.add(item); 949 } 950 } 951 return list; 952 } 953 isVerifyValidInHspMode(Utility utility)954 private static boolean isVerifyValidInHspMode(Utility utility) { 955 if (utility.getJsonPath().isEmpty()) { 956 String errMsg = "--json-path is empty."; 957 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 958 return false; 959 } 960 961 if (!isPathValid(utility.getJsonPath(), TYPE_FILE, MODULE_PROFILE)) { 962 String errMsg = "--json-path must be the module.json file."; 963 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 964 return false; 965 } 966 967 if ((isBundleTypeShared(utility) || isBundleTypeAppService(utility))) { 968 boolean hspHasAbilities = hspHasAbilities(utility); 969 boolean hspHasExtensionAbilities = hspHasExtensionAbilities(utility); 970 if (hspHasAbilities && hspHasExtensionAbilities) { 971 String errMsg = "shared/appService hsp has abilities and extensionAbilities."; 972 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 973 return false; 974 } 975 if (hspHasAbilities) { 976 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString("shared/appService hsp has abilities.")); 977 return false; 978 } 979 if (hspHasExtensionAbilities) { 980 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString("shared/appService hsp has extensionAbilities.")); 981 return false; 982 } 983 } 984 985 if(hasHomeAbility(utility)) { 986 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString("hsp has entry ability.")); 987 return false; 988 } 989 990 if (hasHomeExtensionAbility(utility)) { 991 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString("hsp has entry extensionAbility.")); 992 return false; 993 } 994 995 if (!utility.getJarPath().isEmpty() 996 && !compatibleProcess(utility, utility.getJarPath(), utility.getFormattedJarPathList(), JAR_SUFFIX)) { 997 String errMsg = "--jar-path is invalid."; 998 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 999 return false; 1000 } 1001 1002 if (!utility.getTxtPath().isEmpty() 1003 && !compatibleProcess(utility, utility.getTxtPath(), utility.getFormattedTxtPathList(), TXT_SUFFIX)) { 1004 String errMsg = "--txt-path is invalid."; 1005 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1006 return false; 1007 } 1008 1009 if (!utility.getLibPath().isEmpty() && !isPathValid(utility.getLibPath(), TYPE_DIR, null)) { 1010 String errMsg = "--lib-path is invalid."; 1011 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1012 return false; 1013 } 1014 1015 if (!utility.getResPath().isEmpty() && !isPathValid(utility.getResPath(), TYPE_DIR, null)) { 1016 String errMsg = "--res-path is invalid."; 1017 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1018 return false; 1019 } 1020 1021 if (!utility.getResourcesPath().isEmpty() && !isPathValid(utility.getResourcesPath(), TYPE_DIR, null)) { 1022 String errMsg = "--resources-path is invalid."; 1023 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1024 return false; 1025 } 1026 1027 if (!utility.getAssetsPath().isEmpty() && !isPathValid(utility.getAssetsPath(), TYPE_DIR, null)) { 1028 String errMsg = "--assets-path is invalid."; 1029 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1030 return false; 1031 } 1032 1033 if (!utility.getDirList().isEmpty() && !splitDirList(utility, utility.getDirList(), 1034 utility.getFormatedDirList())) { 1035 String errMsg = "--dir-list is invalid."; 1036 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1037 return false; 1038 } 1039 1040 if (isHapPathValid(utility.getAPPath())) { 1041 String errMsg = "--ap-path is invalid."; 1042 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1043 return false; 1044 } 1045 1046 if (isHapPathValid(utility.getANPath())) { 1047 String errMsg = "--an-path is invalid."; 1048 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1049 return false; 1050 } 1051 1052 if (!utility.getPkgContextPath().isEmpty()) { 1053 File file = new File(utility.getPkgContextPath()); 1054 if (!file.isFile() || !PKG_CONTEXT_INFO.equals(file.getName())) { 1055 String errMsg = "--pkg-context-path file must be the pkgContextInfo.json file."; 1056 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1057 return false; 1058 } 1059 } 1060 1061 if (!utility.getEtsPath().isEmpty() && !isPathExists(utility.getEtsPath())) { 1062 String errMsg = "--ets-path is invalid."; 1063 LOG.error(PackingToolErrMsg.HSP_MODE_ARGS_INVALID.toString(errMsg)); 1064 return false; 1065 } 1066 1067 return isOutPathValid(utility, HSP_SUFFIX); 1068 } 1069 isVerifyValidInHapAdditionMode(Utility utility)1070 private static boolean isVerifyValidInHapAdditionMode(Utility utility) { 1071 if (utility.getHapPath().isEmpty()) { 1072 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode hapPath is empty."); 1073 return false; 1074 } 1075 String hapPath = utility.getAbsoluteHapPath(); 1076 File hapFile = new File(hapPath); 1077 if (hapFile.isDirectory()) { 1078 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode hapPath cannot be a folder."); 1079 return false; 1080 } 1081 if (!(hapPath.endsWith(HAP_SUFFIX) || hapPath.endsWith(HSP_SUFFIX))) { 1082 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode hapPath is invalid."); 1083 return false; 1084 } 1085 if (!hapFile.exists()) { 1086 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode hap file does not exist."); 1087 return false; 1088 } 1089 if (utility.getJsonPath().isEmpty()) { 1090 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode jsonPath is empty."); 1091 return false; 1092 } 1093 if (!utility.getJsonPath().endsWith(JSON_SUFFIX)) { 1094 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode jsonPath is invalid."); 1095 return false; 1096 } 1097 File jsonFile = new File(utility.getJsonPath()); 1098 if (!jsonFile.exists()) { 1099 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode json file does not exist."); 1100 return false; 1101 } 1102 if (!checkJsonIsValid(jsonFile)) { 1103 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode json format is incorrect."); 1104 return false; 1105 } 1106 1107 if (utility.getOutPath().isEmpty()) { 1108 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode outPath is empty."); 1109 return false; 1110 } 1111 File dir = new File(utility.getOutPath()); 1112 if (dir.exists() && dir.isFile()) { 1113 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode outPath is file."); 1114 return false; 1115 } 1116 File absoluteHapFile = new File(utility.getAbsoluteHapPath()); 1117 String hapFileName = absoluteHapFile.getName(); 1118 String destPath = utility.getOutPath() + LINUX_FILE_SEPARATOR + hapFileName; 1119 File destFile = new File(destPath); 1120 if ("false".equals(utility.getForceRewrite()) && destFile.exists()) { 1121 LOG.error("CompressVerify::isVerifyValidInHapAdditionMode target file already exists."); 1122 return false; 1123 } 1124 return true; 1125 } 1126 checkJsonIsValid(File jsonFile)1127 private static boolean checkJsonIsValid(File jsonFile) { 1128 StringBuffer jsonData = new StringBuffer(); 1129 try (FileReader fileReader = new FileReader(jsonFile); 1130 Reader reader = new InputStreamReader(new FileInputStream(jsonFile), StandardCharsets.UTF_8)) { 1131 int ch = 0; 1132 while ((ch = reader.read()) != -1) { 1133 jsonData.append((char) ch); 1134 } 1135 } catch (IOException e) { 1136 LOG.error("CompressVerify::CheckJsonIsValid failed: " + e.getMessage()); 1137 return false; 1138 } 1139 JSONValidator validator = JSONValidator.from(jsonData.toString()); 1140 return validator.validate(); 1141 } 1142 isSharedApp(Utility utility)1143 private static boolean isSharedApp(Utility utility) { 1144 if (!utility.getHapPath().isEmpty()) { 1145 return false; 1146 } 1147 if (utility.getHspPath().isEmpty()) { 1148 return false; 1149 } 1150 List<String> tmpHspPathList = new ArrayList<>(); 1151 if (compatibleProcess(utility, utility.getHspPath(), tmpHspPathList, HSP_SUFFIX) 1152 && verifyIsSharedApp(tmpHspPathList)) { 1153 utility.setIsSharedApp(true); 1154 return true; 1155 } 1156 return false; 1157 } 1158 isAppService(Utility utility)1159 private static boolean isAppService(Utility utility) { 1160 if (!utility.getHapPath().isEmpty()) { 1161 List<String> tmpHapPathList = new ArrayList<>(); 1162 if (compatibleProcess(utility, utility.getHapPath(), tmpHapPathList, HSP_SUFFIX) 1163 && verifyIsAppService(tmpHapPathList)) { 1164 utility.setIsAppService(true); 1165 return true; 1166 } 1167 } 1168 if (utility.getHspPath().isEmpty()) { 1169 return false; 1170 } 1171 List<String> tmpHspPathList = new ArrayList<>(); 1172 if (compatibleProcess(utility, utility.getHspPath(), tmpHspPathList, HSP_SUFFIX) 1173 && verifyIsAppService(tmpHspPathList)) { 1174 utility.setIsAppService(true); 1175 return true; 1176 } 1177 return false; 1178 } verifyIsAppService(List<String> modulePathList)1179 private static boolean verifyIsAppService(List<String> modulePathList) { 1180 if (modulePathList.isEmpty()) { 1181 return false; 1182 } 1183 try { 1184 for (String modulePath : modulePathList) { 1185 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(modulePath); 1186 if (!hapVerifyInfo.getBundleType().equals(BUNDLE_TYPE_APP_SERVICE)) { 1187 return false; 1188 } 1189 } 1190 } catch (BundleException e) { 1191 return false; 1192 } 1193 return true; 1194 } verifyIsSharedApp(List<String> hspPath)1195 private static boolean verifyIsSharedApp(List<String> hspPath) { 1196 try { 1197 HapVerifyInfo hapVerifyInfo = Compressor.parseStageHapVerifyInfo(hspPath.get(0)); 1198 return hapVerifyInfo.getBundleType().equals(BUNDLE_TYPE_SHARE); 1199 } catch (BundleException e) { 1200 return false; 1201 } 1202 } 1203 isBundleTypeShared(Utility utility)1204 private static boolean isBundleTypeShared(Utility utility) { 1205 try { 1206 Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath()); 1207 if(optional.isPresent()) { 1208 return ModuleJsonUtil.parseStageBundleType(optional.get()).equals(BUNDLE_TYPE_SHARE); 1209 } else { 1210 String errMsg = "Parse --json-path content failed."; 1211 LOG.error(PackingToolErrMsg.BUNDLE_TYPE_SHARED_INVALID.toString(errMsg)); 1212 return false; 1213 } 1214 } catch (BundleException e) { 1215 LOG.error(PackingToolErrMsg.BUNDLE_TYPE_SHARED_INVALID.toString("BundleException: " + e.getMessage())); 1216 return false; 1217 } 1218 } 1219 isBundleTypeAppService(Utility utility)1220 private static boolean isBundleTypeAppService(Utility utility) { 1221 try { 1222 Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath()); 1223 if(optional.isPresent()) { 1224 return ModuleJsonUtil.parseStageBundleType(optional.get()).equals(BUNDLE_TYPE_APP_SERVICE); 1225 } else { 1226 String errMsg = "Parse --json-path content failed."; 1227 LOG.error(PackingToolErrMsg.BUNDLE_TYPE_APPSERVICE_INVALID.toString(errMsg)); 1228 return false; 1229 } 1230 } catch (BundleException e) { 1231 LOG.error(PackingToolErrMsg.BUNDLE_TYPE_APPSERVICE_INVALID.toString("BundleException: " + e.getMessage())); 1232 return false; 1233 } 1234 } 1235 hspHasAbilities(Utility utility)1236 private static boolean hspHasAbilities(Utility utility) { 1237 try { 1238 Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath()); 1239 if(optional.isPresent()) { 1240 return ModuleJsonUtil.parseModuleType(optional.get()).equals(BUNDLE_TYPE_SHARE) && !ModuleJsonUtil.parseAbilityNames(optional.get()).isEmpty(); 1241 } else { 1242 String errMsg = "Parse --json-path content failed."; 1243 LOG.error(PackingToolErrMsg.HSP_HAS_ABILITIES_FAILED.toString(errMsg)); 1244 return false; 1245 } 1246 } catch (BundleException e) { 1247 LOG.error(PackingToolErrMsg.HSP_HAS_ABILITIES_FAILED.toString("BundleException: " + e.getMessage())); 1248 return false; 1249 } 1250 } 1251 hspHasExtensionAbilities(Utility utility)1252 private static boolean hspHasExtensionAbilities(Utility utility) { 1253 try { 1254 Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath()); 1255 if (optional.isPresent()) { 1256 return ModuleJsonUtil.parseModuleType(optional.get()).equals(BUNDLE_TYPE_SHARE) && 1257 !ModuleJsonUtil.parseExtensionAbilityName(optional.get()).isEmpty(); 1258 } else { 1259 String errMsg = "Parse --json-path content failed."; 1260 LOG.error(PackingToolErrMsg.HSP_HAS_EXTENSION_ABILITIES_FAILED.toString(errMsg)); 1261 } 1262 } catch (BundleException e) { 1263 LOG.error(PackingToolErrMsg.HSP_HAS_EXTENSION_ABILITIES_FAILED.toString("BundleException: " + e.getMessage())); 1264 } 1265 return false; 1266 } 1267 hasHomeAbility(Utility utility)1268 private static boolean hasHomeAbility(Utility utility) { 1269 try { 1270 boolean result = false; 1271 Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath()); 1272 if(!optional.isPresent()) { 1273 String errMsg = "Parse --json-path content failed."; 1274 LOG.error(PackingToolErrMsg.HAS_HOME_ABILITY_INVALID.toString(errMsg)); 1275 return false; 1276 } 1277 Map<String, Boolean> abilitiesMap = ModuleJsonUtil.parseAbilitySkillsMap(optional.get()); 1278 if (abilitiesMap.containsValue(true)) { 1279 result = true; 1280 } 1281 LOG.info("CompressVerify::hasHomeAbilities result = " + result); 1282 return result; 1283 } catch (BundleException e) { 1284 LOG.error(PackingToolErrMsg.HAS_HOME_ABILITY_INVALID.toString("BundleException: " + e.getMessage())); 1285 return false; 1286 } 1287 } 1288 1289 /** 1290 * Indicates whether the "--encrypt-path" parameter is valid. 1291 * 1292 * @param utility - compress parameters 1293 * @return true if "--encrypt-path" param exists and the file name is encrypt.json, or the "--encrypt-path" 1294 * param is empty, or has no "--encrypt-path" param 1295 * false other situations 1296 */ isValidEncryptJsonFile(Utility utility)1297 private static boolean isValidEncryptJsonFile(Utility utility) { 1298 if (!utility.getEncryptPath().isEmpty()) { 1299 File fileEncryptJson = new File(utility.getEncryptPath()); 1300 return fileEncryptJson.isFile() && Constants.FILE_ENCRYPT_JSON.equals(fileEncryptJson.getName()); 1301 } 1302 return true; 1303 } 1304 hasHomeExtensionAbility(Utility utility)1305 private static boolean hasHomeExtensionAbility(Utility utility) { 1306 try { 1307 boolean result = false; 1308 Optional<String> optional = FileUtils.getFileContent(utility.getJsonPath()); 1309 if (!optional.isPresent()) { 1310 String errMsg = "Parse --json-path content failed."; 1311 LOG.error(PackingToolErrMsg.HAS_HOME_EXTENSION_ABILITY_INVALID.toString(errMsg)); 1312 return false; 1313 } 1314 Map<String, Boolean> extensionAbilitiesMap = ModuleJsonUtil.parseExtensionAbilitySkillsMap(optional.get()); 1315 if (extensionAbilitiesMap.containsValue(true)) { 1316 result = true; 1317 } 1318 LOG.info("CompressVerify::hasHomeExtensionAbility result = " + result); 1319 return result; 1320 } catch (BundleException e) { 1321 LOG.error(PackingToolErrMsg.HAS_HOME_EXTENSION_ABILITY_INVALID.toString("BundleException: " + e.getMessage())); 1322 return false; 1323 } 1324 } 1325 } 1326