Uploaded image for project: 'Commons JEXL'
  1. Commons JEXL
  2. JEXL-330

JexlException.Parsing.getMessage() throws StringIndexOutOfBoundsException when parse error is in long expression

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.1
    • 3.2
    • None

    Description

      JEXL makes some nice diagnostic messages available from Exception.getMessage(). However, in the case where a JexlException.Parsing is thrown in the middle of a long expression,  getMessage() throws a StringIndexOutOfBoundsException instead of returning a nice diagnostic message.

      I encountered this in JEXL 3.1, but have confirmed that it is reproducible using a recent clone of the GitHub repository.

      Impact:
      In the case where the JEXL programmer includes the badly-formed expression, my program, which uses JEXL, throws an unhanded exception, instead of printing out a clear message to the JEXL programmer.

      Steps to Reproduce: 

      @Test
      public void testLongParseError() throws IOException {
          JexlEngine jexl = new JexlBuilder().create();
      
          // Extended form of: 'literal' + VARIABLE   'literal'
          // missing + operator here ---------------^
          String longExpression = "" + //
              "'THIS IS A VERY VERY VERY VERY VERY VERY VERY " + //
              "VERY VERY LONG STRING CONCATENATION ' + VARIABLE ' <--- " + //
              "error: missing + between VARIABLE and literal'";
      
          try {
              jexl.createExpression(longExpression);
              Assert.fail("parsing malformed expression did not throw exception");
          } catch (JexlException.Parsing exception) {
              Assert.assertEquals("???", exception.getMessage());
          }
      }
      

       

      What Happens:

      createExpression() throws a JexlException.Parsing, as expected.
      Calling getMessage() on the resulting JexlException.Parsing, in turn, throws StringIndexOutOfBoundsException.

       

      Expected Result:
      getMessage() returns a brief description of the syntax error.

       

      Technical Details:
      The problem might be in JexlException.parseError. In the case where the expression is long (in this case, the part after the VARIABLE), it tries to extract a snippet of the error.

      protected String parserError(String prefix, String expr) {
          int length = expr.length();
          if (length < MAX_EXCHARLOC) {
              return prefix + " error in '" + expr + "'";
          } else {
              int begin = info.getColumn(); // <---- column in original expression, not within expr
                                            //        In this case, begin > length
              int end = begin + (MAX_EXCHARLOC / 2);
              begin -= (MAX_EXCHARLOC / 2);
              if (begin < 0) {
                  end -= begin;
                  begin = 0;
              }
              return prefix + " error near '... "
                      + expr.substring(begin, end > length ? length : end) + " ...'";
          }
      }
      

      However, the expression that it's given is already an extract, not the entire line:

      ' <--- error: missing + between VARIABLE and literal'

      info.getColumn() returns an index in the original expression, which is already already past the end of the expr.  So when JexlException.parseError invokes expr.substring(), it throws StringIndexOutOfBoundsException.

      Attachments

        Activity

          People

            henrib Henri Biestro
            david_costanzo David Costanzo
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: