From 541dae36d4d1fd1aed3cffc048c2397e31332613 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Wed, 10 Jan 2018 17:39:58 +0000 Subject: [PATCH] Util: New util to truncate a string that won't split across a surrogate pair --- .../org/klomp/snark/web/I2PSnarkServlet.java | 2 +- .../src/net/i2p/servlet/util/ServletUtil.java | 19 +++++++++++++++++++ .../i2p/router/web/helpers/SummaryHelper.java | 3 ++- .../src/src/i2p/susi/webmail/Mail.java | 5 +++-- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index bb156c7afe..ef99d12d48 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -1534,7 +1534,7 @@ public class I2PSnarkServlet extends BasicServlet { String basename = snark.getBaseName(); String fullBasename = basename; if (basename.length() > MAX_DISPLAYED_FILENAME_LENGTH) { - String start = basename.substring(0, MAX_DISPLAYED_FILENAME_LENGTH); + String start = ServletUtil.truncate(basename, MAX_DISPLAYED_FILENAME_LENGTH); if (start.indexOf(' ') < 0 && start.indexOf('-') < 0) { // browser has nowhere to break it basename = start + HELLIP; diff --git a/apps/jetty/java/src/net/i2p/servlet/util/ServletUtil.java b/apps/jetty/java/src/net/i2p/servlet/util/ServletUtil.java index 82c4500d1a..243ffbed74 100644 --- a/apps/jetty/java/src/net/i2p/servlet/util/ServletUtil.java +++ b/apps/jetty/java/src/net/i2p/servlet/util/ServletUtil.java @@ -61,4 +61,23 @@ public class ServletUtil { ua.startsWith("SEC-") || ua.startsWith("SonyEricsson") || ua.startsWith("Vodafone"); } + + /** + * Truncate a String. + * Same as s.substring(0, len) except that + * it won't split a surrogate pair. + * + * @param s non-null + * @return s if shorter; s.substring(0, len) if + * the char at len-1 is not a high surrogate; + * s.substring(0, len+1) if it is + * @since 0.9.33 + */ + public static String truncate(String s, int len) { + if (s.length() <= len) + return s; + if (Character.isHighSurrogate(s.charAt(len - 1))) + return s.substring(0, len + 1); + return s.substring(0, len); + } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/SummaryHelper.java index 4596249aaa..a487f84ff1 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/SummaryHelper.java @@ -28,6 +28,7 @@ import net.i2p.router.transport.TransportUtil; import net.i2p.router.web.CSSHelper; import net.i2p.router.web.HelperBase; import net.i2p.router.web.NewsHelper; +import net.i2p.servlet.util.ServletUtil; import net.i2p.stat.Rate; import net.i2p.stat.RateStat; import net.i2p.util.PortMapper; @@ -575,7 +576,7 @@ public class SummaryHelper extends HelperBase { if (name.length() <= 32) buf.append(DataHelper.escapeHTML(name)); else - buf.append(DataHelper.escapeHTML(name.substring(0,29))).append("…"); + buf.append(DataHelper.escapeHTML(ServletUtil.truncate(name, 29))).append("…"); buf.append("</a></b></td>\n"); LeaseSet ls = _context.netDb().lookupLeaseSetLocally(h); if (ls != null && _context.tunnelManager().getOutboundClientTunnelCount(h) > 0) { diff --git a/apps/susimail/src/src/i2p/susi/webmail/Mail.java b/apps/susimail/src/src/i2p/susi/webmail/Mail.java index f8e8458371..ce11e2bd8b 100644 --- a/apps/susimail/src/src/i2p/susi/webmail/Mail.java +++ b/apps/susimail/src/src/i2p/susi/webmail/Mail.java @@ -43,6 +43,7 @@ import java.util.TimeZone; import java.util.regex.Pattern; import net.i2p.data.DataHelper; +import net.i2p.servlet.util.ServletUtil; import net.i2p.util.SystemVersion; /** @@ -334,7 +335,7 @@ class Mail { shortSender = '<' + shortSender + '>'; // add missing <> (but thunderbird doesn't...) boolean trim = shortSender.length() > 35; if (trim) - shortSender = shortSender.substring( 0, 32 ).trim(); + shortSender = ServletUtil.truncate(shortSender, 32).trim(); shortSender = html.encode( shortSender ); if (trim) shortSender += "…"; // must be after html encode @@ -361,7 +362,7 @@ class Mail { shortSubject = formattedSubject; boolean trim = formattedSubject.length() > 65; if (trim) - shortSubject = formattedSubject.substring( 0, 62 ).trim(); + shortSubject = ServletUtil.truncate(formattedSubject, 62).trim(); shortSubject = html.encode( shortSubject ); if (trim) shortSubject += "…"; // must be after html encode -- GitLab