Skip to content

Commit 6a5d527

Browse files
authored
Refactor string.substring usages to account for surrogate pair characters (#7206)
1 parent 6276356 commit 6a5d527

16 files changed

Lines changed: 32 additions & 19 deletions

File tree

api/src/org/labkey/api/data/Container.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import org.labkey.api.util.NetworkDrive;
6262
import org.labkey.api.util.PageFlowUtil;
6363
import org.labkey.api.util.Path;
64+
import org.labkey.api.util.StringUtilsLabKey;
6465
import org.labkey.api.util.logging.LogHelper;
6566
import org.labkey.api.view.ActionURL;
6667
import org.labkey.api.view.FolderTab;
@@ -1594,7 +1595,7 @@ public String getContainerNoun(boolean titleCase)
15941595
String noun = _containerType.getContainerNoun(this);
15951596
if (titleCase)
15961597
{
1597-
return noun.substring(0, 1).toUpperCase() + noun.substring(1);
1598+
return StringUtilsLabKey.leftSurrogatePairFriendly(noun, 1).toUpperCase() + StringUtilsLabKey.rightSurrogatePairFriendly(noun, noun.length() - 1);
15981599
}
15991600

16001601
return noun;

api/src/org/labkey/api/data/ExcelCellUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.apache.poi.ss.usermodel.CellStyle;
99
import org.apache.poi.ss.usermodel.Workbook;
1010
import org.labkey.api.util.DateUtil;
11+
import org.labkey.api.util.StringUtilsLabKey;
1112

1213
import java.io.File;
1314
import java.math.BigDecimal;
@@ -188,7 +189,7 @@ public static void writeCell(Cell cell, CellStyle style, int simpleType, String
188189
// Check if the string is too long
189190
if (s.length() > 32767)
190191
{
191-
s = s.substring(0, 32762) + "...";
192+
s = StringUtilsLabKey.leftSurrogatePairFriendly(s, 32762) + "...";
192193
}
193194
// Ensure the row is tall enough to show the full values when there are newlines
194195
int newlines = StringUtils.countMatches(s, '\n');

api/src/org/labkey/api/data/ExcelWriter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.apache.poi.ss.usermodel.Workbook;
3737
import org.apache.poi.ss.util.CellRangeAddress;
3838
import org.apache.poi.ss.util.WorkbookUtil;
39+
import org.labkey.api.util.StringUtilsLabKey;
3940
import org.apache.poi.xssf.streaming.SXSSFSheet;
4041
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
4142
import org.jetbrains.annotations.NotNull;
@@ -375,7 +376,7 @@ public void setSheetName(String sheetName)
375376
sheetName = "Sheet";
376377

377378
if (sheetName.length() > 31)
378-
return cleanSheetName(sheetName.substring(0, 31));
379+
return cleanSheetName(StringUtilsLabKey.leftSurrogatePairFriendly(sheetName, 31));
379380

380381
return WorkbookUtil.createSafeSheetName(sheetName, '_');
381382
}

api/src/org/labkey/api/data/SQLFragment.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.labkey.api.util.GUID;
3131
import org.labkey.api.util.JdbcUtil;
3232
import org.labkey.api.util.Pair;
33+
import org.labkey.api.util.StringUtilsLabKey;
3334

3435
import java.math.BigDecimal;
3536
import java.math.BigInteger;
@@ -754,7 +755,7 @@ public boolean appendComment(String comment, SqlDialect dialect)
754755
sb.append("\n-- ");
755756
boolean truncated = comment.length() > 1000;
756757
if (truncated)
757-
comment = comment.substring(0,1000);
758+
comment = StringUtilsLabKey.leftSurrogatePairFriendly(comment, 1000);
758759
sb.append(comment);
759760
if (StringUtils.countMatches(comment, "'")%2==1)
760761
sb.append("'");

api/src/org/labkey/api/data/TSVWriter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.junit.Assert;
2121
import org.junit.Test;
2222
import org.labkey.api.util.FileUtil;
23+
import org.labkey.api.util.StringUtilsLabKey;
2324

2425
import java.io.IOException;
2526
import java.io.PrintWriter;
@@ -109,7 +110,7 @@ public void setFilenamePrefix(String filenamePrefix)
109110
_filenamePrefix = badChars.matcher(filenamePrefix).replaceAll("_");
110111

111112
if (_filenamePrefix.length() > 30)
112-
_filenamePrefix = _filenamePrefix.substring(0, 30);
113+
_filenamePrefix = StringUtilsLabKey.leftSurrogatePairFriendly(_filenamePrefix, 30);
113114
}
114115

115116
public void setDelimiterCharacter(char delimiter)

api/src/org/labkey/api/data/dialect/StatementWrapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.labkey.api.util.DebugInfoDumper;
3535
import org.labkey.api.util.ExceptionUtil;
3636
import org.labkey.api.util.MemTracker;
37+
import org.labkey.api.util.StringUtilsLabKey;
3738
import org.labkey.api.view.ViewServlet;
3839

3940
import java.io.InputStream;
@@ -2876,7 +2877,7 @@ else if (o instanceof String)
28762877
else
28772878
value = String.valueOf(o);
28782879
if (value.length() > 100)
2879-
value = value.substring(0, 100) + ". . .";
2880+
value = StringUtilsLabKey.leftSurrogatePairFriendly(value, 100) + ". . .";
28802881
logEntry.append("\n --[").append(i).append("] ");
28812882
logEntry.append(value);
28822883
Class<?> c = null==o ? null : o.getClass();

api/src/org/labkey/api/exp/OntologyManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import org.labkey.api.util.HtmlString;
6666
import org.labkey.api.util.HtmlStringBuilder;
6767
import org.labkey.api.util.Pair;
68+
import org.labkey.api.util.StringUtilsLabKey;
6869
import org.labkey.api.util.ResultSetUtil;
6970
import org.labkey.api.util.TestContext;
7071
import org.labkey.api.view.HttpView;
@@ -767,7 +768,7 @@ public static boolean validateProperty(List<? extends IPropertyValidator> valida
767768
int stringLength = value == null ? 0 : value.toString().length();
768769
if (value != null && prop.isStringType() && stringLength > stringLengthLimit)
769770
{
770-
String s = stringLength < 100 ? value.toString() : value.toString().substring(0, 100);
771+
String s = stringLength <= 100 ? value.toString() : StringUtilsLabKey.leftSurrogatePairFriendly(value.toString(), 100);
771772
errors.add(new PropertyValidationError("Field '" + prop.getName() + "' is limited to " + stringLengthLimit + " characters, but the value is " + stringLength + " characters. (The value starts with '" + s + "...')", prop.getName()));
772773
ret = false;
773774
}

api/src/org/labkey/api/jsp/LabKeyJspWriter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.labkey.api.util.DOM;
2121
import org.labkey.api.util.HelpTopic;
2222
import org.labkey.api.util.SafeToRender;
23+
import org.labkey.api.util.StringUtilsLabKey;
2324

2425
import jakarta.servlet.jsp.JspWriter;
2526
import java.io.IOException;
@@ -44,7 +45,7 @@ private String truncateAndQuote(String s)
4445
{
4546
return null;
4647
}
47-
return "'" + (s.length() < 50 ? s : (s.substring(0, 50) + "...")) + "'";
48+
return "'" + (s.length() < 50 ? s : (StringUtilsLabKey.leftSurrogatePairFriendly(s, 50) + "...")) + "'";
4849
}
4950

5051
@Override

api/src/org/labkey/api/util/MemTracker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public String getClassName()
138138
public String getObjectSummary()
139139
{
140140
String desc = getObjectDescription();
141-
return desc.length() > 50 ? desc.substring(0, 50) + "..." : desc;
141+
return desc.length() > 50 ? StringUtilsLabKey.leftSurrogatePairFriendly(desc, 50) + "..." : desc;
142142
}
143143

144144
public boolean hasShortSummary()

core/src/org/labkey/core/admin/AdminController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9796,7 +9796,7 @@ public void validateCommand(TabActionForm form, Errors errors)
97969796
}
97979797

97989798
if (name.length() > 50)
9799-
name = name.substring(0, 50).trim();
9799+
name = StringUtilsLabKey.leftSurrogatePairFriendly(name, 50).trim();
98009800

98019801
CaseInsensitiveHashMap<Portal.PortalPage> pages = new CaseInsensitiveHashMap<>(Portal.getPages(tabContainer, true));
98029802
CaseInsensitiveHashMap<FolderTab> folderTabMap = new CaseInsensitiveHashMap<>();
@@ -9850,7 +9850,7 @@ public ApiResponse execute(TabActionForm form, BindException errors)
98509850
// The name, which shows up on the url, is trimmed to 50 characters. The caption, which is derived from the
98519851
// name, and is editable, is allowed to be 64 characters.
98529852
if (name.length() > 50)
9853-
name = name.substring(0, 50).trim();
9853+
name = StringUtilsLabKey.leftSurrogatePairFriendly(name, 50).trim();
98549854

98559855
Portal.saveParts(container, name);
98569856
Portal.addProperty(container, name, Portal.PROP_CUSTOMTAB);

0 commit comments

Comments
 (0)