8000 Fix FPs in S5994 and S6002 by Swalkyn · Pull Request #269 · SonarSource/sonar-analyzer-commons · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix FPs in S5994 and S6002 #269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void visitLookAround(LookAroundTree tree) {
private boolean doesLookaheadContinuationAlwaysFail(LookAroundTree lookAround) {
RegexTree lookAroundElement = lookAround.getElement();
SubAutomaton lookAroundSubAutomaton;
SubAutomaton continuationSubAutomaton = new SubAutomaton(lookAround.continuation(), finalState, getBranchRangeFor(lookAround), true);
SubAutomaton continuationSubAutomaton = new SubAutomaton(lookAround.continuation(), finalState, getPredecessorsRangeOf(lookAround), true);

if (lookAround.getPolarity() == LookAroundTree.Polarity.NEGATIVE) {
lookAroundSubAutomaton = new SubAutomaton(lookAroundElement, lookAroundElement.continuation(), false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private boolean doesRepetitionContinuationAlwaysFail(RepetitionTree repetitionTr
}

SubAutomaton potentialSuperset = new SubAutomaton(repetitionTree.getElement(), repetitionTree.getElement().continuation(), false);
SubAutomaton potentialSubset = new SubAutomaton(repetitionTree.continuation(), finalState, getBranchRangeFor(repetitionTree), true);
SubAutomaton potentialSubset = new SubAutomaton(repetitionTree.continuation(), finalState, getPredecessorsRangeOf(repetitionTree), true);
return RegexTreeHelper.supersetOf(potentialSuperset, potentialSubset, false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@
*/
package org.sonarsource.analyzer.commons.regex.helpers;

import org.sonarsource.analyzer.commons.regex.ast.AbstractRegexSyntaxElement;
import org.sonarsource.analyzer.commons.regex.ast.DisjunctionTree;
import org.sonarsource.analyzer.commons.regex.ast.IndexRange;
import org.sonarsource.analyzer.commons.regex.ast.RegexBaseVisitor;
import org.sonarsource.analyzer.commons.regex.ast.RegexTree;
import org.sonarsource.analyzer.commons.regex.ast.RepetitionTree;

/**
* The BranchTrackingVisitor saves the nearest enclosing branching construct as it traverses the tree. This is useful to
* avoid cycles during Automaton evaluation.
* The BranchTrackingVisitor saves the nearest enclosing branching construct as it traverses the tree. This helps to
* track node predecessors, which is useful to avoid cycles during Automaton evaluation.
*/
public class BranchTrackingVisitor extends RegexBaseVisitor {
private RegexTree branchingNode = null;
Expand All @@ -50,24 +49,35 @@ public void visitRepetition(RepetitionTree tree) {
}

/**
* Return the range of a node's branch. A branch is a group of nodes which are always traversed together by the
* automaton.
* Return the starting index of a node's first predecessors. If all paths from a node lead to another, then the former
* is a predecessor of the latter.
* @param tree a node
* @return IndexRange of the node's branch.
* @return starting index of the node's first predecessor
*/
public IndexRange getBranchRangeFor(RegexTree tree) {
private int getPredecessorsStartOf(RegexTree tree) {
if (branchingNode == null) {
return IndexRange.inaccessible();
return 0;
} else {
if (branchingNode.is(RegexTree.Kind.REPETITION)) {
return ((RepetitionTree) branchingNode).getElement().getRange();
return ((RepetitionTree) branchingNode).getElement().getRange().getBeginningOffset();
} else {
return ((DisjunctionTree) branchingNode).getAlternatives().stream()
.filter(alternative -> alternative.getRange().contains(tree.getRange()))
.findFirst()
.map(AbstractRegexSyntaxElement::getRange)
.orElse(IndexRange.inaccessible());
.map(alternative -> alternative.getRange().getBeginningOffset())
.orElse(tree.getRange().getBeginningOffset());
}
}
}

/**
* Return the range containing all predecessors of the node. If all paths from a node lead to another, then the former
* is a predecessor of the latter
* @param tree a node
* @return IndexRange for all the node's predecessors
*/
public IndexRange getPredecessorsRangeOf(RegexTree tree) {
int firstPredecessorIndex = getPredecessorsStartOf(tree);
return new IndexRange(firstPredecessorIndex, tree.getRange().getEndingOffset());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
- '(?:(x|y)(?!bc))+bc' # Noncompliant

- '(?:a(?!bc)|d)+bc'
- '(?!a)b?|b'
- '(?=a)a|b'
- '(?:(?!b)(a))?'
- '(?:a((?!bc)|d)*)+bc'
- 'a(?!:abc):ab'
- '(?:-(?:one|[0-9]+([a-z](?=[^a-z]|$)|st|nd|rd|th)?))*'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
- 'a+?abc'
- 'a*+\s'
- 'aa++bc'
- 'a++b?|b'
- 'a(?:bc++d?|e)|g'
- '(?:0x)?(\\p{XDigit}++)\\s++(?:U\\+|0x)?(\\p{XDigit}++)(?:\\s++#.*)?'
- '0x(\\p{XDigit}++)\\s++U\\+(\\p{XDigit}++)(\\s++#.*)?'
- '\d*+(?<=[02468])'
- '(:[0-9])?+(:[0-9])?+'
- '(?(1)(.*)|())'
0