Skip to content
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

VariableNameUtils#generateVariableName() should consider following statements #2776

Open
knutwannheden opened this issue Feb 5, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@knutwannheden
Copy link
Contributor

knutwannheden commented Feb 5, 2023

When using VariableNameUtils#generateVariableName() to generate variable names to be inserted at a given position in the code (like it is being used in the ZipSlip recipe of rewrite-java-security, which is the only use I found), then the logic should also consider the statements that follow the given cursor (which will roughly be the insertion point for the variable), otherwise when a new variable is inserted it could conflict with following variables.

In the following example the utility would for a base name of s calculate the name s1 even if that conflicts with a variable that follows. Thus, inserting a variable would render the class uncompilable.

class A {
  void test() {
    String s = null;
    ; // <-- insert new variable with base name "s" here
    String s1 = null;
  }
}

I am currently facing this issue in the InstanceOfPatternMatch recipe.

@knutwannheden knutwannheden added the bug Something isn't working label Feb 5, 2023
@knutwannheden
Copy link
Contributor Author

Also note that VariableNameUtils is currently unaware of the flow scope introduced by the instanceof pattern matching. See the following test, where the commented out test cases should actually also succeed. At least the probe1 case should be supported. I think the others are probably quite rare.

    @ParameterizedTest
    @CsvSource(value = {
//      "probe1:probe1,s1,o",
      "probe2:probe2,o",
      "probe3:probe3,probe2,o",
//      "probe4:probe4,n,probe2,o",
//      "probe5:probe5,n,probe2,o",
    }, delimiter = ':')
    void instanceOfPatternFlowScope(String scope, String result) {
        rewriteRun(
          baseTest(scope, result),
          java(
            """
              class Test {
                  void m(Object o) {
                      if (o instanceof String s1) {
                          Object probe1 = s1;
                      }
                      Object probe2;
                      if (!(o instanceof Number n)) {
                          Object probe3;
                          throw new IllegalStateException();
                      } else {
                          Object probe4 = n;
                      }
                      Object probe5 = n;
                  }
              }
              """
          )
        );
    }

@traceyyoshima I should probably report a separate issue for this. What do you think?

@traceyyoshima
Copy link
Contributor

Also note that VariableNameUtils is currently unaware of the flow scope introduced by the instanceof pattern matching. See the following test, where the commented out test cases should actually also succeed. At least the probe1 case should be supported. I think the others are probably quite rare.

Hi @knutwannheden, yes, I think these should be two separate issues to make the work clearer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Backlog
Development

No branches or pull requests

2 participants