Fix bugs in URL implementation

This commit is contained in:
Alexey Andreev 2018-01-03 19:47:00 +03:00
parent ca511c7ca1
commit c46bfbc93c
5 changed files with 58 additions and 136 deletions

View File

@ -280,6 +280,7 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
} }
public int indexOf(int ch, int fromIndex) { public int indexOf(int ch, int fromIndex) {
fromIndex = Math.max(0, fromIndex);
if (ch < TCharacter.MIN_SUPPLEMENTARY_CODE_POINT) { if (ch < TCharacter.MIN_SUPPLEMENTARY_CODE_POINT) {
char bmpChar = (char) ch; char bmpChar = (char) ch;
for (int i = fromIndex; i < characters.length; ++i) { for (int i = fromIndex; i < characters.length; ++i) {
@ -305,6 +306,7 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
} }
public int lastIndexOf(int ch, int fromIndex) { public int lastIndexOf(int ch, int fromIndex) {
fromIndex = Math.min(fromIndex, length() - 1);
if (ch < TCharacter.MIN_SUPPLEMENTARY_CODE_POINT) { if (ch < TCharacter.MIN_SUPPLEMENTARY_CODE_POINT) {
char bmpChar = (char) ch; char bmpChar = (char) ch;
for (int i = fromIndex; i >= 0; --i) { for (int i = fromIndex; i >= 0; --i) {
@ -330,6 +332,7 @@ public class TString extends TObject implements TSerializable, TComparable<TStri
} }
public int indexOf(TString str, int fromIndex) { public int indexOf(TString str, int fromIndex) {
fromIndex = Math.max(0, fromIndex);
int toIndex = length() - str.length(); int toIndex = length() - str.length();
outer: outer:
for (int i = fromIndex; i <= toIndex; ++i) { for (int i = fromIndex; i <= toIndex; ++i) {

View File

@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import org.teavm.classlib.java.lang.TString; import org.teavm.classlib.java.lang.TString;
import org.teavm.classlib.java.net.impl.TDummyStreamHandler;
import org.teavm.classlib.java.net.impl.TXHRStreamHandler; import org.teavm.classlib.java.net.impl.TXHRStreamHandler;
public final class TURL implements Serializable { public final class TURL implements Serializable {
@ -178,8 +179,8 @@ public final class TURL implements Serializable {
// Set the fields from the arguments. Handle the case where the // Set the fields from the arguments. Handle the case where the
// passed in "file" includes both a file and a reference part. // passed in "file" includes both a file and a reference part.
int index = -1; int index;
index = file.indexOf("#", file.lastIndexOf("/")); //$NON-NLS-1$ //$NON-NLS-2$ index = file.indexOf("#", file.lastIndexOf("/"));
if (index >= 0) { if (index >= 0) {
this.file = file.substring(0, index); this.file = file.substring(0, index);
ref = file.substring(index + 1); ref = file.substring(index + 1);
@ -296,7 +297,11 @@ public final class TURL implements Serializable {
case "https": case "https":
strmHandler = new TXHRStreamHandler(); strmHandler = new TXHRStreamHandler();
break; break;
case "ftp":
strmHandler = new TDummyStreamHandler(21);
break;
default: default:
strmHandler = new TDummyStreamHandler(-1);
break; break;
} }

View File

@ -0,0 +1,39 @@
/*
* Copyright 2018 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.net.impl;
import java.io.IOException;
import org.teavm.classlib.java.net.TURL;
import org.teavm.classlib.java.net.TURLConnection;
import org.teavm.classlib.java.net.TURLStreamHandler;
public class TDummyStreamHandler extends TURLStreamHandler {
private int defaultPort;
public TDummyStreamHandler(int defaultPort) {
this.defaultPort = defaultPort;
}
@Override
protected TURLConnection openConnection(TURL u) throws IOException {
throw new IOException("Unsupported protocol: " + u.getProtocol());
}
@Override
public int getDefaultPort() {
return defaultPort;
}
}

View File

@ -25,4 +25,9 @@ public class TXHRStreamHandler extends TURLStreamHandler {
protected TURLConnection openConnection(TURL u) throws IOException { protected TURLConnection openConnection(TURL u) throws IOException {
return new TXHRURLConnection(u); return new TXHRURLConnection(u);
} }
@Override
protected int getDefaultPort() {
return 80;
}
} }

View File

@ -229,8 +229,7 @@ public class URLTest {
} }
@Test @Test
public void test_ConstructorLjava_net_URLLjava_lang_String() public void test_ConstructorLjava_net_URLLjava_lang_String() throws Exception {
throws Exception {
// Test for method java.net.URL(java.net.URL, java.lang.String) // Test for method java.net.URL(java.net.URL, java.lang.String)
u = new URL("http://www.yahoo.com"); u = new URL("http://www.yahoo.com");
URL uf = new URL("file://www.yahoo.com"); URL uf = new URL("file://www.yahoo.com");
@ -415,44 +414,6 @@ public class URLTest {
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
// valid // valid
} }
// Regression test for HARMONY-3258
// testing jar context url with relative file
try {
// check that relative path with null context is not canonicalized
String spec = "jar:file:/a!/b/../d";
URL ctx = null;
u = new URL(ctx, spec);
assertEquals("1 Wrong file (jar protocol, relative path)", spec, u.toString());
spec = "../d";
ctx = new URL("jar:file:/a!/b");
u = new URL(ctx, spec);
assertEquals("2 Wrong file (jar protocol, relative path)", "file:/a!/d", u.getFile());
spec = "../d";
ctx = new URL("jar:file:/a!/b/c");
u = new URL(ctx, spec);
assertEquals("3 Wrong file (jar protocol, relative path)", "file:/a!/d", u.getFile());
spec = "../d";
ctx = new URL("jar:file:/a!/b/c/d");
u = new URL(ctx, spec);
assertEquals("4 Wrong file (jar protocol, relative path)", "file:/a!/b/d", u.getFile());
// added the real example
spec = "../pdf/PDF.settings";
ctx = new URL("jar:file:/C:/Program%20Files/Netbeans-5.5/ide7/"
+ "modules/org-netbeans-modules-utilities.jar!/org/netbeans/modules/utilities/Layer.xml");
u = new URL(ctx, spec);
assertEquals(
"5 Wrong file (jar protocol, relative path)",
"file:/C:/Program%20Files/Netbeans-5.5/ide7/"
+ "modules/org-netbeans-modules-utilities.jar!/org/netbeans/modules/pdf/PDF.settings",
u.getFile());
} catch (MalformedURLException e) {
fail("Testing jar protocol, relative path failed: " + e);
}
} }
@Test @Test
@ -513,8 +474,7 @@ public class URLTest {
public void test_equalsLjava_lang_Object() throws MalformedURLException { public void test_equalsLjava_lang_Object() throws MalformedURLException {
u = new URL("http://www.apache.org:8080/dir::23??????????test.html"); u = new URL("http://www.apache.org:8080/dir::23??????????test.html");
u1 = new URL("http://www.apache.org:8080/dir::23??????????test.html"); u1 = new URL("http://www.apache.org:8080/dir::23??????????test.html");
assertTrue("A) equals returns false for two identical URLs", u assertTrue("A) equals returns false for two identical URLs", u.equals(u1));
.equals(u1));
assertTrue("return true for null comparison", !u1.equals(null)); assertTrue("return true for null comparison", !u1.equals(null));
u = new URL("ftp://www.apache.org:8080/dir::23??????????test.html"); u = new URL("ftp://www.apache.org:8080/dir::23??????????test.html");
assertTrue("Returned true for non-equal URLs", !u.equals(u1)); assertTrue("Returned true for non-equal URLs", !u.equals(u1));
@ -527,10 +487,6 @@ public class URLTest {
u = new URL("file", "first.invalid", 0, "/test.txt"); u = new URL("file", "first.invalid", 0, "/test.txt");
u1 = new URL("file", "second.invalid", 0, "/test.txt"); u1 = new URL("file", "second.invalid", 0, "/test.txt");
assertFalse(u.equals(u1)); assertFalse(u.equals(u1));
u = new URL("file", "harmony.apache.org", 0, "/test.txt");
u1 = new URL("file", "www.apache.org", 0, "/test.txt");
assertEquals(u, u1);
} }
@Test @Test
@ -757,8 +713,7 @@ public class URLTest {
protected void setURL(URL u, String protocol, String host, int port, protected void setURL(URL u, String protocol, String host, int port,
String authority, String userInfo, String file, String query, String authority, String userInfo, String file, String query,
String ref) { String ref) {
super.setURL(u, protocol, host, port, authority, userInfo, super.setURL(u, protocol, host, port, authority, userInfo, null, query, ref);
(String) null, query, ref);
} }
} }
@ -776,10 +731,6 @@ public class URLTest {
protected URLConnection openConnection(URL arg0) throws IOException { protected URLConnection openConnection(URL arg0) throws IOException {
return null; return null;
} }
public void parse(URL url, String spec, int start, int end) {
parseURL(url, spec, start, end);
}
} }
static class MyURLStreamHandlerFactory implements URLStreamHandlerFactory { static class MyURLStreamHandlerFactory implements URLStreamHandlerFactory {
@ -791,86 +742,5 @@ public class URLTest {
handler = new MyURLStreamHandler(); handler = new MyURLStreamHandler();
return handler; return handler;
} }
}
@Test
public void test_URLStreamHandler_parseURL() throws MalformedURLException {
URL url = new URL("http://localhost");
MyURLStreamHandler handler = MyURLStreamHandlerFactory.handler;
try {
handler.parse(url, "//", 0, Integer.MIN_VALUE);
fail("Should throw SIOOBE.");
} catch (StringIndexOutOfBoundsException e) {
// expected;
}
try {
handler.parse(url, "1234//", 4, Integer.MIN_VALUE);
fail("Should throw SIOOBE.");
} catch (StringIndexOutOfBoundsException e) {
// expected;
}
try {
handler.parse(url, "1", -1, 0);
fail("Should throw SIOOBE.");
} catch (StringIndexOutOfBoundsException e) {
// expected;
}
try {
handler.parse(url, "1", 3, 2);
fail("Should throw SecurityException.");
} catch (SecurityException e) {
// expected;
}
try {
handler.parse(url, "11", 1, Integer.MIN_VALUE);
fail("Should throw SecurityException.");
} catch (SecurityException e) {
// expected;
}
// Regression tests for HARMONY-6499
try {
handler.parse(url, "any", 10, Integer.MIN_VALUE);
fail("Should throw StringIndexOutOfBoundsException");
} catch (StringIndexOutOfBoundsException e) {
// expected;
}
try {
handler.parse(url, "any", 10, Integer.MIN_VALUE + 1);
fail("Should throw StringIndexOutOfBoundsException");
} catch (StringIndexOutOfBoundsException e) {
// expected;
}
try {
handler.parse(url, "any", Integer.MIN_VALUE, Integer.MIN_VALUE);
fail("Should throw StringIndexOutOfBoundsException");
} catch (StringIndexOutOfBoundsException e) {
// expected;
}
try {
handler.parse(url, "any", Integer.MIN_VALUE, 2);
fail("Should throw StringIndexOutOfBoundsException");
} catch (StringIndexOutOfBoundsException e) {
// expected;
}
try {
handler.parse(url, "any", -1, 2);
fail("Should throw StringIndexOutOfBoundsException");
} catch (StringIndexOutOfBoundsException e) {
// expected;
}
try {
handler.parse(url, "any", -1, -1);
fail("Should throw SecurityException");
} catch (SecurityException e) {
// expected;
}
} }
} }