■ ■ ■ ■ ■ ■
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java
| skipped 460 lines |
461 | 461 | | } |
462 | 462 | | } |
463 | 463 | | |
464 | | - | if (elseBlock != null) { |
465 | | - | if (stack.containsExit(elseBlock)) { |
466 | | - | elseBlock = null; |
467 | | - | } else if (elseBlock.getAttributes().contains(AttributeFlag.RETURN)) { |
468 | | - | out = elseBlock; |
469 | | - | elseBlock = null; |
470 | | - | } |
| 464 | + | if (elseBlock != null && stack.containsExit(elseBlock)) { |
| 465 | + | elseBlock = null; |
471 | 466 | | } |
472 | 467 | | |
473 | 468 | | stack.push(ifRegion); |
| skipped 7 lines |
481 | 476 | | } |
482 | 477 | | |
483 | 478 | | private IfInfo mergeNestedIfNodes(BlockNode block, BlockNode bThen, BlockNode bElse, List<BlockNode> merged) { |
| 479 | + | IfInfo info = new IfInfo(); |
| 480 | + | info.setIfnode(block); |
| 481 | + | info.setCondition(IfCondition.fromIfBlock(block)); |
| 482 | + | info.setThenBlock(bThen); |
| 483 | + | info.setElseBlock(bElse); |
| 484 | + | return mergeNestedIfNodes(info, merged); |
| 485 | + | } |
| 486 | + | |
| 487 | + | private IfInfo mergeNestedIfNodes(IfInfo info, List<BlockNode> merged) { |
| 488 | + | BlockNode bThen = info.getThenBlock(); |
| 489 | + | BlockNode bElse = info.getElseBlock(); |
484 | 490 | | if (bThen == bElse) { |
485 | 491 | | return null; |
486 | 492 | | } |
487 | 493 | | |
488 | | - | boolean found; |
489 | | - | IfCondition condition = IfCondition.fromIfBlock(block); |
490 | | - | IfInfo result = null; |
491 | | - | do { |
492 | | - | found = false; |
493 | | - | for (BlockNode succ : block.getSuccessors()) { |
494 | | - | BlockNode nestedIfBlock = getIfNode(succ); |
495 | | - | if (nestedIfBlock != null && nestedIfBlock != block) { |
496 | | - | IfNode nestedIfInsn = (IfNode) nestedIfBlock.getInstructions().get(0); |
497 | | - | BlockNode nbThen = nestedIfInsn.getThenBlock(); |
498 | | - | BlockNode nbElse = nestedIfInsn.getElseBlock(); |
499 | | - | |
500 | | - | boolean inverted = false; |
501 | | - | IfCondition nestedCondition = IfCondition.fromIfNode(nestedIfInsn); |
502 | | - | if (isPathExists(bElse, nestedIfBlock)) { |
503 | | - | // else branch |
504 | | - | if (!isEqualPaths(bThen, nbThen)) { |
505 | | - | if (!isEqualPaths(bThen, nbElse)) { |
506 | | - | // not connected conditions |
507 | | - | break; |
508 | | - | } |
509 | | - | nestedIfInsn.invertCondition(); |
510 | | - | inverted = true; |
511 | | - | } |
512 | | - | condition = IfCondition.merge(Mode.OR, condition, nestedCondition); |
513 | | - | } else { |
514 | | - | // then branch |
515 | | - | if (!isEqualPaths(bElse, nbElse)) { |
516 | | - | if (!isEqualPaths(bElse, nbThen)) { |
517 | | - | // not connected conditions |
518 | | - | break; |
519 | | - | } |
520 | | - | nestedIfInsn.invertCondition(); |
521 | | - | inverted = true; |
522 | | - | } |
523 | | - | condition = IfCondition.merge(Mode.AND, condition, nestedCondition); |
524 | | - | } |
525 | | - | result = new IfInfo(); |
526 | | - | result.setCondition(condition); |
527 | | - | nestedIfBlock.getAttributes().add(AttributeFlag.SKIP); |
528 | | - | skipSimplePath(bThen); |
529 | | - | |
530 | | - | if (merged != null) { |
531 | | - | merged.add(nestedIfBlock); |
532 | | - | } |
| 494 | + | BlockNode ifBlock = info.getIfnode(); |
| 495 | + | BlockNode nestedIfBlock = getNextIfBlock(ifBlock); |
| 496 | + | if (nestedIfBlock == null) { |
| 497 | + | return null; |
| 498 | + | } |
533 | 499 | | |
534 | | - | // set new blocks |
535 | | - | result.setIfnode(nestedIfBlock); |
536 | | - | result.setThenBlock(inverted ? nbElse : nbThen); |
537 | | - | result.setElseBlock(inverted ? nbThen : nbElse); |
| 500 | + | IfNode nestedIfInsn = (IfNode) nestedIfBlock.getInstructions().get(0); |
| 501 | + | IfCondition nestedCondition = IfCondition.fromIfNode(nestedIfInsn); |
| 502 | + | BlockNode nbThen = nestedIfInsn.getThenBlock(); |
| 503 | + | BlockNode nbElse = nestedIfInsn.getElseBlock(); |
538 | 504 | | |
539 | | - | found = true; |
540 | | - | block = nestedIfBlock; |
541 | | - | bThen = result.getThenBlock(); |
542 | | - | bElse = result.getElseBlock(); |
543 | | - | break; |
| 505 | + | IfCondition condition = info.getCondition(); |
| 506 | + | boolean inverted = false; |
| 507 | + | if (isPathExists(bElse, nestedIfBlock)) { |
| 508 | + | // else branch |
| 509 | + | if (!isEqualPaths(bThen, nbThen)) { |
| 510 | + | if (!isEqualPaths(bThen, nbElse)) { |
| 511 | + | // not connected conditions |
| 512 | + | return null; |
| 513 | + | } |
| 514 | + | nestedIfInsn.invertCondition(); |
| 515 | + | inverted = true; |
| 516 | + | } |
| 517 | + | condition = IfCondition.merge(Mode.OR, condition, nestedCondition); |
| 518 | + | } else { |
| 519 | + | // then branch |
| 520 | + | if (!isEqualPaths(bElse, nbElse)) { |
| 521 | + | if (!isEqualPaths(bElse, nbThen)) { |
| 522 | + | // not connected conditions |
| 523 | + | return null; |
544 | 524 | | } |
| 525 | + | nestedIfInsn.invertCondition(); |
| 526 | + | inverted = true; |
545 | 527 | | } |
546 | | - | } while (found); |
| 528 | + | condition = IfCondition.merge(Mode.AND, condition, nestedCondition); |
| 529 | + | } |
| 530 | + | if (merged != null) { |
| 531 | + | merged.add(nestedIfBlock); |
| 532 | + | } |
| 533 | + | nestedIfBlock.getAttributes().add(AttributeFlag.SKIP); |
| 534 | + | BlockNode blockToNestedIfBlock = BlockUtils.getNextBlockToPath(ifBlock, nestedIfBlock); |
| 535 | + | skipSimplePath(BlockUtils.selectOther(blockToNestedIfBlock, ifBlock.getCleanSuccessors())); |
| 536 | + | |
| 537 | + | IfInfo result = new IfInfo(); |
| 538 | + | result.setIfnode(nestedIfBlock); |
| 539 | + | result.setCondition(condition); |
| 540 | + | result.setThenBlock(inverted ? nbElse : nbThen); |
| 541 | + | result.setElseBlock(inverted ? nbThen : nbElse); |
547 | 542 | | |
| 543 | + | // search next nested if block |
| 544 | + | IfInfo next = mergeNestedIfNodes(result, merged); |
| 545 | + | if (next != null) { |
| 546 | + | return next; |
| 547 | + | } |
548 | 548 | | return result; |
| 549 | + | } |
| 550 | + | |
| 551 | + | private BlockNode getNextIfBlock(BlockNode block) { |
| 552 | + | for (BlockNode succ : block.getSuccessors()) { |
| 553 | + | BlockNode nestedIfBlock = getIfNode(succ); |
| 554 | + | if (nestedIfBlock != null && nestedIfBlock != block) { |
| 555 | + | return nestedIfBlock; |
| 556 | + | } |
| 557 | + | } |
| 558 | + | return null; |
549 | 559 | | } |
550 | 560 | | |
551 | 561 | | private static BlockNode getIfNode(BlockNode block) { |
| skipped 197 lines |