This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit d062d965a951d5fb7082938660e6333ca0c7a174
Author: opencode <[email protected]>
AuthorDate: Sun Oct 18 20:47:18 2026 +0200

    Fix jspc handling of the full stop (--) argument
    
    The full stop argument was never advanced past by nextArg(), while
    nextFile() incremented the argument position on every call when the
    full stop had been seen. The net result was that every second file
    argument after '--' was silently skipped, e.g. 'jspc -- a.jsp b.jsp
    c.jsp' only processed a.jsp and c.jsp.
    
    nextArg() now consumes the full stop argument exactly once and
    nextFile() no longer manipulates the argument position, so all
    remaining arguments are collected as files. In addition, the rewind
    for the first non-option argument is now unconditional, and option
    parsing stops whenever the full stop argument is consumed, including
    when it appears in an option value position, so that option-like
    arguments after '--' are treated as files. As a side effect, the
    previously possible infinite loop caused by a full stop argument
    directly after -trimSpaces no longer occurs.
    
    Add regression tests for the full stop argument handling to
    TestJspC.
---
 java/org/apache/jasper/JspC.java     | 39 ++++++++++++++++++++-------------
 test/org/apache/jasper/TestJspC.java | 42 ++++++++++++++++++++++++++++++++++++
 webapps/docs/changelog.xml           | 12 +++++++++++
 3 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/java/org/apache/jasper/JspC.java b/java/org/apache/jasper/JspC.java
index 4e6f0278b5..6b22c771f7 100644
--- a/java/org/apache/jasper/JspC.java
+++ b/java/org/apache/jasper/JspC.java
@@ -508,12 +508,16 @@ public class JspC extends Task implements Options {
                 if (tok.startsWith("-")) {
                     throw new 
JasperException(Localizer.getMessage("jspc.error.unknownOption", tok));
                 }
-                if (!fullstop) {
-                    argPos--;
-                }
+                // Re-process this argument as a JSP page
+                argPos--;
                 // Start treating the rest as JSP Pages
                 break;
             }
+            if (fullstop) {
+                // A full stop argument encountered while reading an option
+                // value also stops option parsing
+                break;
+            }
         }
 
         // Add all extra arguments to the list of files
@@ -1691,32 +1695,37 @@ public class JspC extends Task implements Options {
     // ==================== protected utility methods ====================
 
     /**
-     * Returns the next command-line argument.
+     * Returns the next command-line argument. Option parsing stops when the
+     * full stop argument {@code --} is encountered. The full stop argument is
+     * consumed and is never returned.
      *
-     * @return the next argument, or {@code null} if no more arguments
+     * @return the next argument, or {@code null} if no more arguments are
+     *             available or the full stop argument was reached
      */
     protected String nextArg() {
-        if ((argPos >= args.length) || (fullstop = 
SWITCH_FULL_STOP.equals(args[argPos]))) {
+        if (argPos >= args.length) {
             return null;
-        } else {
-            return args[argPos++];
         }
+        if (SWITCH_FULL_STOP.equals(args[argPos])) {
+            fullstop = true;
+            argPos++;
+            return null;
+        }
+        return args[argPos++];
     }
 
     /**
-     * Returns the next file argument from the command-line.
+     * Returns the next file argument from the command-line. All remaining
+     * arguments are treated as files once option parsing has stopped.
      *
-     * @return the next file argument, or {@code null} if no more arguments
+     * @return the next file argument, or {@code null} if no more arguments are
+     *             available
      */
     protected String nextFile() {
-        if (fullstop) {
-            argPos++;
-        }
         if (argPos >= args.length) {
             return null;
-        } else {
-            return args[argPos++];
         }
+        return args[argPos++];
     }
 
     /**
diff --git a/test/org/apache/jasper/TestJspC.java 
b/test/org/apache/jasper/TestJspC.java
index b4fd22620c..ebcc7e9051 100644
--- a/test/org/apache/jasper/TestJspC.java
+++ b/test/org/apache/jasper/TestJspC.java
@@ -110,6 +110,48 @@ public class TestJspC {
     }
 
     @Test
+    public void argsNoFullStop() throws Exception {
+        jspc.setArgs(new String[] {"a.jsp", "b.jsp"});
+        Assert.assertEquals(List.of("a.jsp", "b.jsp"), jspc.pages);
+    }
+
+    @Test
+    public void argsFullStop() throws Exception {
+        jspc.setArgs(new String[] {"--", "a.jsp", "b.jsp", "c.jsp"});
+        Assert.assertEquals(List.of("a.jsp", "b.jsp", "c.jsp"), jspc.pages);
+    }
+
+    @Test
+    public void argsFullStopAfterOptions() throws Exception {
+        jspc.setArgs(new String[] {"-compile", "--", "a.jsp", "b.jsp"});
+        Assert.assertTrue(jspc.compile);
+        Assert.assertEquals(List.of("a.jsp", "b.jsp"), jspc.pages);
+    }
+
+    @Test
+    public void argsFullStopFileStartingWithDash() throws Exception {
+        jspc.setArgs(new String[] {"--", "-a.jsp", "b.jsp"});
+        Assert.assertEquals(List.of("-a.jsp", "b.jsp"), jspc.pages);
+    }
+
+    @Test
+    public void argsFullStopAsOptionValue() throws Exception {
+        // The full stop argument takes the place of the missing option value
+        // and must not cause the first file argument to be dropped
+        jspc.setArgs(new String[] {"-d", "--", "a.jsp", "b.jsp"});
+        Assert.assertEquals(List.of("a.jsp", "b.jsp"), jspc.pages);
+    }
+
+    @Test
+    public void argsFullStopInOptionValuePositionStopsOptionParsing()
+            throws Exception {
+        jspc.setArgs(new String[] {"-cache", "--", "-compile", "a.jsp"});
+        Assert.assertFalse(jspc.compile);
+        Assert.assertEquals(List.of("-compile", "a.jsp"), jspc.pages);
+    }
+
+    @Test
+>>>>>>> 79e8d06f4c (Fix jspc handling of the full stop (--) argument)
     public void servletContextUsesAntLog() throws Exception {
         List<String> messages = new ArrayList<>();
         Project project = new Project();
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 6b645456a4..71c9b266ee 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -390,6 +390,18 @@
       </fix>
     </changelog>
   </subsection>
+  <subsection name="Jasper">
+    <changelog>
+      <fix>
+        Correct the handling of the <code>--</code> argument by
+        <code>jspc</code>. The argument position was advanced past the full
+        stop argument on each iteration while collecting the JSP file
+        arguments, so every second file argument after <code>--</code> was
+        silently omitted from processing. Option parsing now stops at the
+        first full stop argument wherever it appears. (remm)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="WebSocket">
     <changelog>
       <fix>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to