Can anyone please take a look?

Thank you.

> On 25 Sep 2018, at 14:27, Bo Zhang <zhangbo...@gmail.com> wrote:
> 
> Hi all,
> 
> This is my first time to try to submit a patch. Please forgive me if I did 
> anything inappropriate. I’ve signed the OCA with the name “Bo Zhang”.
> 
> Bug description:
> 
> 8210810 <https://bugs.openjdk.java.net/browse/JDK-8210810>: Incorrect 
> argument file parser behavior in certain cases
> 
> Previously, if a quoted backslash character appears at argument file
> parser buffer boundary (i.e. 4096th/8192nd/... character of an argument
> file is backslash '\'), the segment before the backslash character will
> be added into argument twice due to a missing anchor position reset
> operation.
> 
> For example, you have an argument file:
> 
> -cp "...a\\b"
> 
> and the 4096th and 4097th characters happen to be both '\', the result
> generated by the argument file parser would be:
> 
> -cp "...aa\\b”
> 
> This patch fixes the issue by resetting anchor position correctly
> in this case.
> 
> I’m a little surprised that this issue has existed for several years 
> unnoticed.
> 
> 
> Patch:
> 
> # HG changeset patch
> # User Bo Zhang <zhangbo...@gmail.com <mailto:zhangbo...@gmail.com>>
> # Date 1537835887 -28800
> #      Tue Sep 25 08:38:07 2018 +0800
> # Node ID 34f2803ad62cde8c82e3dfcf0b66e80276bd7352
> # Parent  16f0deae8fa6ef85f7230308e1fe7556bd007c39
> 8210810: Incorrect argument file parser behavior in certain cases
> 
> Previously, if a quoted backslash character appears at argument file
> parser buffer boundary (i.e. 4096th/8192nd/... character of an argument
> file is backslash '\'), the segment before the backslash character will
> be added into argument twice due to a missing anchor position reset
> operation.
> 
> For example, you have an argument file:
> 
> -cp "...a\\b"
> 
> and the 4096th and 4097th characters happen to be both '\', the result
> generated by the argument file parser would be:
> 
> -cp "...aa\\b"
> 
> This patch fixes the issue by resetting anchor position correctly
> in this case.
> 
> diff --git a/src/java.base/share/native/libjli/args.c 
> b/src/java.base/share/native/libjli/args.c
> --- a/src/java.base/share/native/libjli/args.c
> +++ b/src/java.base/share/native/libjli/args.c
> @@ -262,6 +262,8 @@
>                      continue;
>                  }
>                  JLI_List_addSubstring(pctx->parts, anchor, nextc - anchor);
> +                // anchor after backslash character
> +                anchor = nextc + 1;
>                  pctx->state = IN_ESCAPE;
>                  break;
>              case '\'':
> diff --git a/test/jdk/tools/launcher/Test8210810.java 
> b/test/jdk/tools/launcher/Test8210810.java
> new file mode 100644
> --- /dev/null
> +++ b/test/jdk/tools/launcher/Test8210810.java
> @@ -0,0 +1,107 @@
> +/*
> + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 only, as
> + * published by the Free Software Foundation.
> + *
> + * This code is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> + * version 2 for more details (a copy is included in the LICENSE file that
> + * accompanied this code).
> + *
> + * You should have received a copy of the GNU General Public License version
> + * 2 along with this work; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
> + * or visit www.oracle.com <http://www.oracle.com/> if you need additional 
> information or have any
> + * questions.
> + */
> +
> +/*
> + * @test
> + * @bug 8210810
> + * @summary Incorrect argument file parser behavior when backslash appears 
> at buffer boundary
> + * @modules java.base
> + * @author Bo Zhang
> + * @build TestHelper
> + * @run main Test8210810
> + */
> +
> +/*
> + * 8210810: Previously, if a quoted backslash character appears at argument 
> file
> + * parser buffer boundary (i.e. 4096th/8192nd/... character of an argument
> + * file is backslash '\'), the segment before the backslash character will
> + * be added into argument twice due to a missing anchor position reset
> + * operation. This test creates a special argument file which can reproduce 
> this issue.
> + */
> +import java.io.File;
> +import java.nio.file.Files;
> +import java.io.IOException;
> +import java.util.Arrays;
> +
> +public class Test8210810 extends TestHelper {
> +    // Buffer size in args.c readArgFile() method
> +    private static final int ARG_FILE_PARSER_BUF_SIZE = 4096;
> +    public static void main(String... args) throws Exception {
> +        new Test8210810().canParseArgFileCorrectly();
> +    }
> +
> +    private void canParseArgFileCorrectly() throws IOException {
> +        File testJar = createTestClassWhichPrintsClasspath();
> +        File argFile = createArgFileWithSpecificClasspath();
> +        TestResult result = doExec(javaCmd, "@argFile", "Foo");
> +
> +        long zCountInArgFile = countZ(new 
> String(Files.readAllBytes(argFile.toPath())));
> +        long zCountReadByParser = countZ(result.testOutput.get(0));
> +        if(zCountInArgFile != zCountReadByParser) {
> +            throw new RuntimeException("Classpath parsed by parser is 
> different from argument file!");
> +        }
> +
> +        testJar.delete();
> +        argFile.delete();
> +    }
> +
> +    private long countZ(String str) {
> +        return str.chars().filter(ch -> ch == 'z').count();
> +    }
> +
> +    private File createTestClassWhichPrintsClasspath() throws IOException {
> +        File testJar = new File("test.jar");
> +        testJar.delete();
> +
> +        StringBuilder tsrc = new StringBuilder();
> +        tsrc.append("public static void main(String... args) {\n");
> +        tsrc.append("   System.out.println(\"Classpath:\" + 
> System.getProperty(\"java.class.path\"));\n");
> +        tsrc.append("}\n");
> +        createJar(testJar, new File("Foo"), tsrc.toString());
> +        return testJar;
> +    }
> +
> +    // Create a file whose 4096th and 4097th characters are both '\' 
> (backslash)
> +    // File content:
> +    // |-cp "test.jar:zzzzz...zzz\\"|
> +    private File createArgFileWithSpecificClasspath() throws IOException {
> +        File argFile = new File("argFile");
> +        argFile.delete();
> +
> +        StringBuilder arg = new StringBuilder("-cp \"test.jar");
> +        arg.append(File.pathSeparator);
> +
> +        int fillingCharactersCount = ARG_FILE_PARSER_BUF_SIZE - 1 - 
> arg.length();
> +
> +        for(int i = 0; i < fillingCharactersCount; ++i) {
> +            arg.append('z');
> +        }
> +
> +        arg.append('\\'); // 4096th character in the arg file
> +        arg.append('\\'); // 4097th character in the arg file
> +        arg.append('"');
> +
> +        createAFile(argFile, Arrays.asList(arg.toString()));
> +        return argFile;
> +    }
> +}
> 
> Unit test:
> 
> Included in the patch. It creates a special argument file whose 4096th and 
> 4097th characters are both ‘\’. Then it compares the classpath read in the VM 
> and the classpath in the argument file to verify they’re identical.
> 
> <8210810.patch>
> 

Reply via email to