Skip to content

Commit

Permalink
8260043: Reduce allocation in sun.net.www.protocol.jar.Handler.parseURL
Browse files Browse the repository at this point in the history
Reviewed-by: redestad, chegar
  • Loading branch information
eirbjo authored and cl4es committed Jan 21, 2021
1 parent 4dfd8cc commit e1de0bf
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 51 deletions.
45 changes: 1 addition & 44 deletions src/java.base/share/classes/sun/net/www/ParseUtil.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2021, 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
Expand Down Expand Up @@ -225,49 +225,6 @@ public static String decode(String s) {
return sb.toString();
}

/**
* Returns a canonical version of the specified string.
*/
public static String canonizeString(String file) {
int len = file.length();
if (len == 0 || (file.indexOf("./") == -1 && file.charAt(len - 1) != '.')) {
return file;
} else {
return doCanonize(file);
}
}

private static String doCanonize(String file) {
int i, lim;

// Remove embedded /../
while ((i = file.indexOf("/../")) >= 0) {
if ((lim = file.lastIndexOf('/', i - 1)) >= 0) {
file = file.substring(0, lim) + file.substring(i + 3);
} else {
file = file.substring(i + 3);
}
}
// Remove embedded /./
while ((i = file.indexOf("/./")) >= 0) {
file = file.substring(0, i) + file.substring(i + 2);
}
// Remove trailing ..
while (file.endsWith("/..")) {
i = file.indexOf("/..");
if ((lim = file.lastIndexOf('/', i - 1)) >= 0) {
file = file.substring(0, lim+1);
} else {
file = file.substring(0, i);
}
}
// Remove trailing .
if (file.endsWith("/."))
file = file.substring(0, file.length() -1);

return file;
}

public static URL fileToEncodedURL(File file)
throws MalformedURLException
{
Expand Down
57 changes: 50 additions & 7 deletions src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, 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
Expand Down Expand Up @@ -27,7 +27,6 @@

import java.io.IOException;
import java.net.*;
import sun.net.www.ParseUtil;

/*
* Jar URL Handler
Expand Down Expand Up @@ -164,12 +163,9 @@ protected void parseURL(URL url, String spec,
} else if (!refOnly) {
file = parseContextSpec(url, spec);

// Canonize the result after the bangslash
// Canonicalize the result after the bangslash
int bangSlash = indexOfBangSlash(file);
String toBangSlash = file.substring(0, bangSlash);
String afterBangSlash = file.substring(bangSlash);
afterBangSlash = ParseUtil.canonizeString(afterBangSlash);
file = toBangSlash + afterBangSlash;
file = canonicalizeString(file, bangSlash);
}
setURL(url, "jar", "", -1, file, ref);
}
Expand Down Expand Up @@ -216,4 +212,51 @@ private String parseContextSpec(URL url, String spec) {
}
return (ctxFile + spec);
}

/**
* Returns a version of the specified string with
* canonicalization applied starting from position {@code off}
*/
private static String canonicalizeString(String file, int off) {
int len = file.length();
if (off >= len || (file.indexOf("./", off) == -1 && file.charAt(len - 1) != '.')) {
return file;
} else {
// Defer substring and concat until canonicalization is required
String before = file.substring(0, off);
String after = file.substring(off);
return before + doCanonicalize(after);
}
}

private static String doCanonicalize(String file) {
int i, lim;

// Remove embedded /../
while ((i = file.indexOf("/../")) >= 0) {
if ((lim = file.lastIndexOf('/', i - 1)) >= 0) {
file = file.substring(0, lim) + file.substring(i + 3);
} else {
file = file.substring(i + 3);
}
}
// Remove embedded /./
while ((i = file.indexOf("/./")) >= 0) {
file = file.substring(0, i) + file.substring(i + 2);
}
// Remove trailing ..
while (file.endsWith("/..")) {
i = file.indexOf("/..");
if ((lim = file.lastIndexOf('/', i - 1)) >= 0) {
file = file.substring(0, lim+1);
} else {
file = file.substring(0, i);
}
}
// Remove trailing .
if (file.endsWith("/."))
file = file.substring(0, file.length() -1);

return file;
}
}

1 comment on commit e1de0bf

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.