Replace StringUtil.toHtml with StringEscapeUtils.escapeHtml

Apache commons is providing Html-escaping, no need to reinvent the wheel:

> It supports all known HTML 4.0 entities, including funky accents. Note that the
> commonly used apostrophe escape character (') is not a legal entity and so
> is not supported).

So I manually checked that nothing is relying on escaped single-quotes,
and didn't manage to find anything that does.
master
jvoisin 5 years ago
parent 9dc9cbd821
commit e1583691d8
  1. 4
      airsonic-main/src/main/java/org/airsonic/player/ajax/CoverArtService.java
  2. 9
      airsonic-main/src/main/java/org/airsonic/player/ajax/NowPlayingService.java
  3. 4
      airsonic-main/src/main/java/org/airsonic/player/controller/SetMusicFileInfoController.java
  4. 8
      airsonic-main/src/main/java/org/airsonic/player/controller/UploadController.java
  5. 43
      airsonic-main/src/main/java/org/airsonic/player/util/StringUtil.java
  6. 20
      airsonic-main/src/test/java/org/airsonic/player/util/StringUtilTestCase.java

@ -25,8 +25,8 @@ import org.airsonic.player.service.LastFmService;
import org.airsonic.player.service.MediaFileService; import org.airsonic.player.service.MediaFileService;
import org.airsonic.player.service.SecurityService; import org.airsonic.player.service.SecurityService;
import org.airsonic.player.util.FileUtil; import org.airsonic.player.util.FileUtil;
import org.airsonic.player.util.StringUtil;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
@ -109,7 +109,7 @@ public class CoverArtService {
// Check permissions. // Check permissions.
File newCoverFile = new File(path, "cover." + suffix); File newCoverFile = new File(path, "cover." + suffix);
if (!securityService.isWriteAllowed(newCoverFile)) { if (!securityService.isWriteAllowed(newCoverFile)) {
throw new Exception("Permission denied: " + StringUtil.toHtml(newCoverFile.getPath())); throw new Exception("Permission denied: " + StringEscapeUtils.escapeHtml(newCoverFile.getPath()));
} }
// If file exists, create a backup. // If file exists, create a backup.

@ -22,6 +22,7 @@ package org.airsonic.player.ajax;
import org.airsonic.player.domain.*; import org.airsonic.player.domain.*;
import org.airsonic.player.service.*; import org.airsonic.player.service.*;
import org.airsonic.player.util.StringUtil; import org.airsonic.player.util.StringUtil;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.directwebremoting.WebContext; import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory; import org.directwebremoting.WebContextFactory;
@ -129,14 +130,14 @@ public class NowPlayingService {
avatarUrl = url + "avatar.view?usernameUtf8Hex=" + StringUtil.utf8HexEncode(username); avatarUrl = url + "avatar.view?usernameUtf8Hex=" + StringUtil.utf8HexEncode(username);
} }
String tooltip = StringUtil.toHtml(artist) + " – " + StringUtil.toHtml(title); String tooltip = StringEscapeUtils.escapeHtml(artist) + " – " + StringEscapeUtils.escapeHtml(title);
if (StringUtils.isNotBlank(player.getName())) { if (StringUtils.isNotBlank(player.getName())) {
username += "@" + player.getName(); username += "@" + player.getName();
} }
artist = StringUtil.toHtml(StringUtils.abbreviate(artist, 25)); artist = StringEscapeUtils.escapeHtml(StringUtils.abbreviate(artist, 25));
title = StringUtil.toHtml(StringUtils.abbreviate(title, 25)); title = StringEscapeUtils.escapeHtml(StringUtils.abbreviate(title, 25));
username = StringUtil.toHtml(StringUtils.abbreviate(username, 25)); username = StringEscapeUtils.escapeHtml(StringUtils.abbreviate(username, 25));
long minutesAgo = status.getMinutesAgo(); long minutesAgo = status.getMinutesAgo();

@ -21,7 +21,7 @@ package org.airsonic.player.controller;
import org.airsonic.player.domain.MediaFile; import org.airsonic.player.domain.MediaFile;
import org.airsonic.player.service.MediaFileService; import org.airsonic.player.service.MediaFileService;
import org.airsonic.player.util.StringUtil; import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestUtils; import org.springframework.web.bind.ServletRequestUtils;
@ -52,7 +52,7 @@ public class SetMusicFileInfoController {
MediaFile mediaFile = mediaFileService.getMediaFile(id); MediaFile mediaFile = mediaFileService.getMediaFile(id);
if ("comment".equals(action)) { if ("comment".equals(action)) {
mediaFile.setComment(StringUtil.toHtml(request.getParameter("comment"))); mediaFile.setComment(StringEscapeUtils.escapeHtml(request.getParameter("comment")));
mediaFileService.updateMediaFile(mediaFile); mediaFileService.updateMediaFile(mediaFile);
} }

@ -28,10 +28,10 @@ import org.airsonic.player.service.StatusService;
import org.airsonic.player.upload.MonitoredDiskFileItemFactory; import org.airsonic.player.upload.MonitoredDiskFileItemFactory;
import org.airsonic.player.upload.UploadListener; import org.airsonic.player.upload.UploadListener;
import org.airsonic.player.util.FileUtil; import org.airsonic.player.util.FileUtil;
import org.airsonic.player.util.StringUtil;
import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringEscapeUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -127,7 +127,7 @@ public class UploadController {
File targetFile = new File(dir, new File(fileName).getName()); File targetFile = new File(dir, new File(fileName).getName());
if (!securityService.isUploadAllowed(targetFile)) { if (!securityService.isUploadAllowed(targetFile)) {
throw new Exception("Permission denied: " + StringUtil.toHtml(targetFile.getPath())); throw new Exception("Permission denied: " + StringEscapeUtils.escapeHtml(targetFile.getPath()));
} }
if (!dir.exists()) { if (!dir.exists()) {
@ -174,13 +174,13 @@ public class UploadController {
ZipEntry entry = (ZipEntry) entries.nextElement(); ZipEntry entry = (ZipEntry) entries.nextElement();
File entryFile = new File(file.getParentFile(), entry.getName()); File entryFile = new File(file.getParentFile(), entry.getName());
if (!entryFile.toPath().normalize().startsWith(file.getParentFile().toPath())) { if (!entryFile.toPath().normalize().startsWith(file.getParentFile().toPath())) {
throw new Exception("Bad zip filename: " + StringUtil.toHtml(entryFile.getPath())); throw new Exception("Bad zip filename: " + StringEscapeUtils.escapeHtml(entryFile.getPath()));
} }
if (!entry.isDirectory()) { if (!entry.isDirectory()) {
if (!securityService.isUploadAllowed(entryFile)) { if (!securityService.isUploadAllowed(entryFile)) {
throw new Exception("Permission denied: " + StringUtil.toHtml(entryFile.getPath())); throw new Exception("Permission denied: " + StringEscapeUtils.escapeHtml(entryFile.getPath()));
} }
entryFile.getParentFile().mkdirs(); entryFile.getParentFile().mkdirs();

@ -20,6 +20,7 @@
package org.airsonic.player.util; package org.airsonic.player.util;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import java.io.*; import java.io.*;
@ -43,14 +44,6 @@ public final class StringUtil {
public static final String ENCODING_UTF8 = "UTF-8"; public static final String ENCODING_UTF8 = "UTF-8";
private static final String[][] HTML_SUBSTITUTIONS = {
{"&", "&"},
{"<", "&lt;"},
{">", "&gt;"},
{"'", "&#39;"},
{"\"", "&#34;"},
};
private static final String[][] MIME_TYPES = { private static final String[][] MIME_TYPES = {
{"mp3", "audio/mpeg"}, {"mp3", "audio/mpeg"},
{"ogg", "audio/ogg"}, {"ogg", "audio/ogg"},
@ -97,40 +90,6 @@ public final class StringUtil {
private StringUtil() { private StringUtil() {
} }
/**
* Returns the specified string converted to a format suitable for
* HTML. All single-quote, double-quote, greater-than, less-than and
* ampersand characters are replaces with their corresponding HTML
* Character Entity code.
*
* @param s the string to convert
* @return the converted string
*/
public static String toHtml(String s) {
if (s == null) {
return null;
}
for (String[] substitution : HTML_SUBSTITUTIONS) {
if (s.contains(substitution[0])) {
s = s.replaceAll(substitution[0], substitution[1]);
}
}
return s;
}
/**
* Removes the suffix (the substring after the last dot) of the given string. The dot is
* also removed.
*
* @param s The string in question, e.g., "foo.mp3".
* @return The string without the suffix, e.g., "foo".
*/
public static String removeSuffix(String s) {
int index = s.lastIndexOf('.');
return index == -1 ? s : s.substring(0, index);
}
/** /**
* Returns the proper MIME type for the given suffix. * Returns the proper MIME type for the given suffix.
* *

@ -20,6 +20,7 @@
package org.airsonic.player.util; package org.airsonic.player.util;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.commons.lang.StringEscapeUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
@ -32,20 +33,11 @@ import java.util.Locale;
public class StringUtilTestCase extends TestCase { public class StringUtilTestCase extends TestCase {
public void testToHtml() { public void testToHtml() {
assertEquals(null, StringUtil.toHtml(null)); assertEquals(null, StringEscapeUtils.escapeHtml(null));
assertEquals("", StringUtil.toHtml("")); assertEquals("", StringEscapeUtils.escapeHtml(""));
assertEquals(" ", StringUtil.toHtml(" ")); assertEquals(" ", StringEscapeUtils.escapeHtml(" "));
assertEquals("q &amp; a", StringUtil.toHtml("q & a")); assertEquals("q &amp; a", StringEscapeUtils.escapeHtml("q & a"));
assertEquals("q &amp; a &lt;&gt; b", StringUtil.toHtml("q & a <> b")); assertEquals("q &amp; a &lt;&gt; b", StringEscapeUtils.escapeHtml("q & a <> b"));
}
public void testRemoveSuffix() {
assertEquals("Error in removeSuffix().", "foo", StringUtil.removeSuffix("foo.mp3"));
assertEquals("Error in removeSuffix().", "", StringUtil.removeSuffix(".mp3"));
assertEquals("Error in removeSuffix().", "foo.bar", StringUtil.removeSuffix("foo.bar.mp3"));
assertEquals("Error in removeSuffix().", "foo.", StringUtil.removeSuffix("foo..mp3"));
assertEquals("Error in removeSuffix().", "foo", StringUtil.removeSuffix("foo"));
assertEquals("Error in removeSuffix().", "", StringUtil.removeSuffix(""));
} }
public void testGetMimeType() { public void testGetMimeType() {

Loading…
Cancel
Save