From 638d612c6b7c08c1f7be0d4e75e9f8a6dca1ef19 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Wed, 8 Feb 2023 19:20:39 +0000 Subject: [PATCH] 8298478: (fs) Path.of should allow input to include long path prefix Reviewed-by: alanb --- .../classes/sun/nio/fs/WindowsPathParser.java | 24 +++++++++++++- test/jdk/java/nio/file/Path/PathOps.java | 32 +++++++++++++++++-- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsPathParser.java b/src/java.base/windows/classes/sun/nio/fs/WindowsPathParser.java index a7afbbe0274..6198fbfd5b5 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsPathParser.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsPathParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -92,6 +92,20 @@ class WindowsPathParser { * Indicates if the path requires to be normalized */ private static Result parse(String input, boolean requireToNormalize) { + // if a prefix is present, remove it and note the expected path type + final WindowsPathType expectedType; + if (input.startsWith("\\\\?\\")) { + if (input.startsWith("UNC\\", 4)) { + expectedType = WindowsPathType.UNC; + input = "\\\\" + input.substring(8); + } else { + expectedType = WindowsPathType.ABSOLUTE; + input = input.substring(4); + } + } else { + expectedType = null; + } + String root = ""; WindowsPathType type = null; @@ -147,6 +161,14 @@ class WindowsPathParser { } } + if (expectedType != null && type != expectedType) { + if (expectedType == WindowsPathType.ABSOLUTE) { // long path prefix + throw new InvalidPathException(input, "Long path prefix can only be used with an absolute path"); + } else if (expectedType == WindowsPathType.UNC) { // long UNC path prefix + throw new InvalidPathException(input, "Long UNC path prefix can only be used with a UNC path"); + } + } + if (requireToNormalize) { StringBuilder sb = new StringBuilder(input.length()); sb.append(root); diff --git a/test/jdk/java/nio/file/Path/PathOps.java b/test/jdk/java/nio/file/Path/PathOps.java index d6992c8ed2c..aa37ddb84ac 100644 --- a/test/jdk/java/nio/file/Path/PathOps.java +++ b/test/jdk/java/nio/file/Path/PathOps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, 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 @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 6925932 7006126 8037945 8072495 8140449 8254876 + * @bug 4313887 6838333 6925932 7006126 8037945 8072495 8140449 8254876 8298478 * @summary Unit test for java.nio.file.Path path operations */ @@ -1437,6 +1437,34 @@ public class PathOps { int h2 = test("c:\\FOO").path().hashCode(); if (h1 != h2) throw new RuntimeException("PathOps failed"); + + // long path prefixes + test("\\\\?\\C:\\mnt\\file.dat") // absolute + .string("C:\\mnt\\file.dat"); + test("\\\\?\\\\\\server\\share\\dir\\file.dat") // UNC + .invalid(); + test("\\\\?\\file.dat") // relative + .invalid(); + test("\\\\?\\\\file.dat") // directory-relative + .invalid(); + test("\\\\?\\C:file.dat") // drive-relative + .invalid(); + test("\\\\?\\") // empty + .invalid(); + + // long UNC path prefixes + test("\\\\?\\UNC\\server\\share\\dir\\file.dat") // UNC + .string("\\\\server\\share\\dir\\file.dat"); + test("\\\\?\\UNC\\server\\share\\C:\\file.dat") // absolute + .invalid(); + test("\\\\?\\UNC\\file.dat") // relative + .invalid(); + test("\\\\?\\UNC\\server\\share\\C:file.dat") // drive-relative + .invalid(); + test("\\\\?\\UNC") // empty + .invalid(); + test("\\\\?\\UNC\\") // empty + .invalid(); } static void doUnixTests() {