83 lines
2.5 KiB
Java
83 lines
2.5 KiB
Java
// Copyright (C) 2013 The Android Open Source Project
|
|
//
|
|
// 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 com.google.gwtexpui.safehtml.client;
|
|
|
|
import com.google.gwt.regexp.shared.RegExp;
|
|
|
|
/**
|
|
* A Find/Replace pair whose replacement string is a link.
|
|
*
|
|
* <p>It is safe to pass arbitrary user-provided links to this class. Links are sanitized as
|
|
* follows:
|
|
*
|
|
* <ul>
|
|
* <li>Only http(s) and mailto links are supported; any other scheme results in an {@link
|
|
* IllegalArgumentException} from {@link #replace(String)}.
|
|
* <li>Special characters in the link after regex replacement are escaped with {@link
|
|
* SafeHtmlBuilder}.
|
|
* </ul>
|
|
*/
|
|
public class LinkFindReplace implements FindReplace {
|
|
public static boolean hasValidScheme(String link) {
|
|
int colon = link.indexOf(':');
|
|
if (colon < 0) {
|
|
return true;
|
|
}
|
|
String scheme = link.substring(0, colon);
|
|
return "http".equalsIgnoreCase(scheme)
|
|
|| "https".equalsIgnoreCase(scheme)
|
|
|| "mailto".equalsIgnoreCase(scheme);
|
|
}
|
|
|
|
private RegExp pat;
|
|
private String link;
|
|
|
|
protected LinkFindReplace() {}
|
|
|
|
/**
|
|
* @param find regular expression pattern to match substrings with.
|
|
* @param link replacement link href. Capture groups within {@code find} can be referenced with
|
|
* {@code $<i>n</i>}.
|
|
*/
|
|
public LinkFindReplace(String find, String link) {
|
|
this.pat = RegExp.compile(find);
|
|
this.link = link;
|
|
}
|
|
|
|
@Override
|
|
public RegExp pattern() {
|
|
return pat;
|
|
}
|
|
|
|
@Override
|
|
public String replace(String input) {
|
|
String href = pat.replace(input, link);
|
|
if (!hasValidScheme(href)) {
|
|
throw new IllegalArgumentException("Invalid scheme (" + toString() + "): " + href);
|
|
}
|
|
return new SafeHtmlBuilder()
|
|
.openAnchor()
|
|
.setAttribute("href", href)
|
|
.append(SafeHtml.asis(input))
|
|
.closeAnchor()
|
|
.asString();
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "find = " + pat.getSource() + ", link = " + link;
|
|
}
|
|
}
|