Skip to content

Commit

Permalink
8278972: Improve URL supports
Browse files Browse the repository at this point in the history
Backport-of: 94f1fbfd6d23f18ade3cc1b36f6dd368963c9d02
  • Loading branch information
Yuri Nesterenko authored and RealCLanger committed Apr 8, 2022
1 parent 463ce03 commit a61b441
Show file tree
Hide file tree
Showing 5 changed files with 648 additions and 73 deletions.
67 changes: 63 additions & 4 deletions src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2022, 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 @@ -28,6 +28,10 @@
import javax.naming.*;
import java.net.MalformedURLException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Locale;
import java.util.StringTokenizer;
import com.sun.jndi.toolkit.url.Uri;
import com.sun.jndi.toolkit.url.UrlUtil;
Expand Down Expand Up @@ -64,6 +68,25 @@

public final class LdapURL extends Uri {

private static final String PARSE_MODE_PROP = "com.sun.jndi.ldapURLParsing";
private static final ParseMode DEFAULT_PARSE_MODE = ParseMode.COMPAT;

public static final ParseMode PARSE_MODE;
static {
PrivilegedAction<String> action = () ->
System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString());
ParseMode parseMode = DEFAULT_PARSE_MODE;
try {
@SuppressWarnings("removal")
String mode = AccessController.doPrivileged(action);
parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT));
} catch (Throwable t) {
parseMode = DEFAULT_PARSE_MODE;
} finally {
PARSE_MODE = parseMode;
}
}

private boolean useSsl = false;
private String DN = null;
private String attributes = null;
Expand All @@ -83,7 +106,7 @@ public LdapURL(String url) throws NamingException {
useSsl = scheme.equalsIgnoreCase("ldaps");

if (! (scheme.equalsIgnoreCase("ldap") || useSsl)) {
throw new MalformedURLException("Not an LDAP URL: " + url);
throw newInvalidURISchemeException(url);
}

parsePathAndQuery(); // DN, attributes, scope, filter, extensions
Expand All @@ -99,6 +122,21 @@ public LdapURL(String url) throws NamingException {
}
}

@Override
protected MalformedURLException newInvalidURISchemeException(String uri) {
return new MalformedURLException("Not an LDAP URL: " + uri);
}

@Override
protected boolean isSchemeOnly(String uri) {
return isLdapSchemeOnly(uri);
}

@Override
protected ParseMode parseMode() {
return PARSE_MODE;
}

/**
* Returns true if the URL is an LDAPS URL.
*/
Expand Down Expand Up @@ -151,13 +189,33 @@ public static String[] fromList(String urlList) throws NamingException {
StringTokenizer st = new StringTokenizer(urlList, " ");

while (st.hasMoreTokens()) {
urls[i++] = st.nextToken();
// we don't accept scheme-only URLs here
urls[i++] = validateURI(st.nextToken());
}
String[] trimmed = new String[i];
System.arraycopy(urls, 0, trimmed, 0, i);
return trimmed;
}

public static boolean isLdapSchemeOnly(String uri) {
return "ldap:".equals(uri) || "ldaps:".equals(uri);
}

public static String validateURI(String uri) {
// no validation in legacy mode parsing
if (PARSE_MODE == ParseMode.LEGACY) {
return uri;
}

// special case of scheme-only URIs
if (isLdapSchemeOnly(uri)) {
return uri;
}

// use java.net.URI to validate the uri syntax
return URI.create(uri).toString();
}

/**
* Determines whether an LDAP URL has query components.
*/
Expand All @@ -181,7 +239,8 @@ static String toUrlString(String host, int port, String dn, boolean useSsl)
String p = (port != -1) ? (":" + port) : "";
String d = (dn != null) ? ("/" + UrlUtil.encode(dn, "UTF8")) : "";

return useSsl ? "ldaps://" + h + p + d : "ldap://" + h + p + d;
String uri = useSsl ? "ldaps://" + h + p + d : "ldap://" + h + p + d;
return validateURI(uri);
} catch (UnsupportedEncodingException e) {
// UTF8 should always be supported
throw new IllegalStateException("UTF-8 encoding unavailable");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2022, 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 @@ -32,6 +32,8 @@
import java.util.Hashtable;
import java.net.MalformedURLException;

import com.sun.jndi.toolkit.url.Uri.ParseMode;

/**
* This abstract class is a generic URL context that accepts as the
* name argument either a string URL or a Name whose first component
Expand All @@ -48,6 +50,7 @@
* @author Rosanna Lee
*/
public abstract class GenericURLContext implements Context {

protected Hashtable<String, Object> myEnv = null;

@SuppressWarnings("unchecked") // Expect Hashtable<String, Object>
Expand Down Expand Up @@ -161,8 +164,18 @@ protected String getURLPrefix(String url) throws NamingException {
if (url.startsWith("//", start)) {
start += 2; // skip double slash

// find last slash
int posn = url.indexOf('/', start);
// find where the authority component ends
// and the rest of the URL starts
int slash = url.indexOf('/', start);
int qmark = url.indexOf('?', start);
int fmark = url.indexOf('#', start);
if (fmark > -1 && qmark > fmark) qmark = -1;
if (fmark > -1 && slash > fmark) slash = -1;
if (qmark > -1 && slash > qmark) slash = -1;
int posn = slash > -1 ? slash
: (qmark > -1 ? qmark
: (fmark > -1 ? fmark
: url.length()));
if (posn >= 0) {
start = posn;
} else {
Expand Down
Loading

0 comments on commit a61b441

Please sign in to comment.