add forbidden api checks for non-Locale toLowerCase and toUpperCase

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1815994 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2017-11-21 22:10:48 +00:00
parent 0675acb64a
commit 268bcdbc2d
7 changed files with 482 additions and 445 deletions

View File

@ -17,6 +17,8 @@
package org.apache.poi.sl.usermodel; package org.apache.poi.sl.usermodel;
import org.apache.poi.util.StringUtil;
/** /**
* known preset shape geometries in PresentationML * known preset shape geometries in PresentationML
*/ */
@ -299,7 +301,7 @@ public enum ShapeType {
toLower = false; toLower = false;
continue; continue;
} }
sb.append(toLower ? Character.toLowerCase(ch) : Character.toUpperCase(ch)); sb.append(toLower ? StringUtil.toLowerCase(ch) : StringUtil.toUpperCase(ch));
toLower = true; toLower = true;
} }

View File

@ -27,6 +27,7 @@ import java.util.Locale;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.StringUtil;
/** /**
* Formats a date value. * Formats a date value.
@ -110,9 +111,9 @@ public class CellDateFormatter extends CellFormatter {
// am/pm marker // am/pm marker
mStart = -1; mStart = -1;
showAmPm = true; showAmPm = true;
showM = Character.toLowerCase(part.charAt(1)) == 'm'; showM = StringUtil.toLowerCase(part.charAt(1)).equals("m");
// For some reason "am/pm" becomes AM or PM, but "a/p" becomes a or p // For some reason "am/pm" becomes AM or PM, but "a/p" becomes a or p
amPmUpper = showM || Character.isUpperCase(part.charAt(0)); amPmUpper = showM || StringUtil.isUpperCase(part.charAt(0));
return "a"; return "a";
} }
@ -199,11 +200,11 @@ public class CellDateFormatter extends CellFormatter {
if (!doneAm) { if (!doneAm) {
if (showAmPm) { if (showAmPm) {
if (amPmUpper) { if (amPmUpper) {
toAppendTo.append(Character.toString(ch).toUpperCase(LocaleUtil.getUserLocale())); toAppendTo.append(StringUtil.toUpperCase(ch));
if (showM) if (showM)
toAppendTo.append('M'); toAppendTo.append('M');
} else { } else {
toAppendTo.append(Character.toString(ch).toLowerCase(LocaleUtil.getUserLocale())); toAppendTo.append(StringUtil.toLowerCase(ch));
if (showM) if (showM)
toAppendTo.append('m'); toAppendTo.append('m');
} }

View File

@ -18,6 +18,7 @@ package org.apache.poi.ss.format;
import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.StringUtil;
import javax.swing.*; import javax.swing.*;
@ -341,7 +342,7 @@ public class CellFormatPart {
char c1 = repl.charAt(0); char c1 = repl.charAt(0);
char c2 = 0; char c2 = 0;
if (repl.length() > 1) if (repl.length() > 1)
c2 = Character.toLowerCase(repl.charAt(1)); c2 = StringUtil.toLowerCase(repl.charAt(1)).charAt(0);
switch (c1) { switch (c1) {
case '@': case '@':

View File

@ -36,7 +36,7 @@ public class StringUtil {
public static final Charset WIN_1252 = Charset.forName("cp1252"); public static final Charset WIN_1252 = Charset.forName("cp1252");
public static final Charset BIG5 = Charset.forName("Big5"); public static final Charset BIG5 = Charset.forName("Big5");
private static Map<Integer,Integer> msCodepointToUnicode; private static Map<Integer, Integer> msCodepointToUnicode;
private StringUtil() { private StringUtil() {
// no instances of this class // no instances of this class
@ -46,7 +46,7 @@ public class StringUtil {
* Given a byte array of 16-bit unicode characters in Little Endian * Given a byte array of 16-bit unicode characters in Little Endian
* format (most important byte last), return a Java String representation * format (most important byte last), return a Java String representation
* of it. * of it.
* * <p>
* { 0x16, 0x00 } -0x16 * { 0x16, 0x00 } -0x16
* *
* @param string the byte array to be converted * @param string the byte array to be converted
@ -55,10 +55,10 @@ public class StringUtil {
* 1 ] contain the first 16-bit unicode character * 1 ] contain the first 16-bit unicode character
* @param len the length of the final string * @param len the length of the final string
* @return the converted string, never <code>null</code>. * @return the converted string, never <code>null</code>.
* @exception ArrayIndexOutOfBoundsException if offset is out of bounds for * @throws ArrayIndexOutOfBoundsException if offset is out of bounds for
* the byte array (i.e., is negative or is greater than or equal to * the byte array (i.e., is negative or is greater than or equal to
* string.length) * string.length)
* @exception IllegalArgumentException if len is too large (i.e., * @throws IllegalArgumentException if len is too large (i.e.,
* there is not enough data in string to create a String of that * there is not enough data in string to create a String of that
* length) * length)
*/ */
@ -81,14 +81,16 @@ public class StringUtil {
* Given a byte array of 16-bit unicode characters in little endian * Given a byte array of 16-bit unicode characters in little endian
* format (most important byte last), return a Java String representation * format (most important byte last), return a Java String representation
* of it. * of it.
* * <p>
* { 0x16, 0x00 } -0x16 * { 0x16, 0x00 } -0x16
* *
* @param string the byte array to be converted * @param string the byte array to be converted
* @return the converted string, never <code>null</code> * @return the converted string, never <code>null</code>
*/ */
public static String getFromUnicodeLE(byte[] string) { public static String getFromUnicodeLE(byte[] string) {
if(string.length == 0) { return ""; } if (string.length == 0) {
return "";
}
return getFromUnicodeLE(string, 0, string.length / 2); return getFromUnicodeLE(string, 0, string.length / 2);
} }
@ -134,7 +136,7 @@ public class StringUtil {
* <li>byte[]/char[] characterData</li> * <li>byte[]/char[] characterData</li>
* </ol> * </ol>
* For this encoding, the is16BitFlag is always present even if nChars==0. * For this encoding, the is16BitFlag is always present even if nChars==0.
* * <p>
* This structure is also known as a XLUnicodeString. * This structure is also known as a XLUnicodeString.
*/ */
public static String readUnicodeString(LittleEndianInput in) { public static String readUnicodeString(LittleEndianInput in) {
@ -146,6 +148,7 @@ public class StringUtil {
} }
return readUnicodeLE(in, nChars); return readUnicodeLE(in, nChars);
} }
/** /**
* InputStream <tt>in</tt> is expected to contain: * InputStream <tt>in</tt> is expected to contain:
* <ol> * <ol>
@ -165,6 +168,7 @@ public class StringUtil {
} }
return readUnicodeLE(in, nChars); return readUnicodeLE(in, nChars);
} }
/** /**
* OutputStream <tt>out</tt> will get: * OutputStream <tt>out</tt> will get:
* <ol> * <ol>
@ -185,6 +189,7 @@ public class StringUtil {
putCompressedUnicode(value, out); putCompressedUnicode(value, out);
} }
} }
/** /**
* OutputStream <tt>out</tt> will get: * OutputStream <tt>out</tt> will get:
* <ol> * <ol>
@ -249,13 +254,14 @@ public class StringUtil {
byte[] bytes = input.getBytes(UTF16LE); byte[] bytes = input.getBytes(UTF16LE);
System.arraycopy(bytes, 0, output, offset, bytes.length); System.arraycopy(bytes, 0, output, offset, bytes.length);
} }
public static void putUnicodeLE(String input, LittleEndianOutput out) { public static void putUnicodeLE(String input, LittleEndianOutput out) {
byte[] bytes = input.getBytes(UTF16LE); byte[] bytes = input.getBytes(UTF16LE);
out.write(bytes); out.write(bytes);
} }
public static String readUnicodeLE(LittleEndianInput in, int nChars) { public static String readUnicodeLE(LittleEndianInput in, int nChars) {
byte[] bytes = IOUtils.safelyAllocate(nChars*2, MAX_RECORD_LENGTH); byte[] bytes = IOUtils.safelyAllocate(nChars * 2, MAX_RECORD_LENGTH);
in.readFully(bytes); in.readFully(bytes);
return new String(bytes, UTF16LE); return new String(bytes, UTF16LE);
} }
@ -316,6 +322,7 @@ public class StringUtil {
public static class StringsIterator implements Iterator<String> { public static class StringsIterator implements Iterator<String> {
private String[] strings = {}; private String[] strings = {};
private int position; private int position;
public StringsIterator(String[] strings) { public StringsIterator(String[] strings) {
if (strings != null) { if (strings != null) {
this.strings = strings.clone(); this.strings = strings.clone();
@ -325,16 +332,34 @@ public class StringUtil {
public boolean hasNext() { public boolean hasNext() {
return position < strings.length; return position < strings.length;
} }
public String next() { public String next() {
int ourPos = position++; int ourPos = position++;
if(ourPos >= strings.length) { if (ourPos >= strings.length) {
throw new ArrayIndexOutOfBoundsException(ourPos); throw new ArrayIndexOutOfBoundsException(ourPos);
} }
return strings[ourPos]; return strings[ourPos];
} }
public void remove() {}
public void remove() {
}
} }
@Internal
public static String toLowerCase(char c) {
return Character.toString(c).toLowerCase(LocaleUtil.getUserLocale());
}
@Internal
public static String toUpperCase(char c) {
return Character.toString(c).toUpperCase(LocaleUtil.getUserLocale());
}
@Internal
public static boolean isUpperCase(char c) {
String s = Character.toString(c);
return s.toUpperCase(LocaleUtil.getUserLocale()).equals(s);
}
/** /**
* Some strings may contain encoded characters of the unicode private use area. * Some strings may contain encoded characters of the unicode private use area.
@ -343,7 +368,6 @@ public class StringUtil {
* *
* @param string the original string * @param string the original string
* @return the string with mapped characters * @return the string with mapped characters
*
* @see <a href="http://www.alanwood.net/unicode/private_use_area.html#symbol">Private Use Area (symbol)</a> * @see <a href="http://www.alanwood.net/unicode/private_use_area.html#symbol">Private Use Area (symbol)</a>
* @see <a href="http://www.alanwood.net/demos/symbol.html">Symbol font - Unicode alternatives for Greek and special characters in HTML</a> * @see <a href="http://www.alanwood.net/demos/symbol.html">Symbol font - Unicode alternatives for Greek and special characters in HTML</a>
*/ */
@ -371,7 +395,7 @@ public class StringUtil {
private static synchronized void initMsCodepointMap() { private static synchronized void initMsCodepointMap() {
if (msCodepointToUnicode != null) return; if (msCodepointToUnicode != null) return;
msCodepointToUnicode = new HashMap<>(); msCodepointToUnicode = new HashMap<>();
int i=0xF020; int i = 0xF020;
for (int ch : symbolMap_f020) { for (int ch : symbolMap_f020) {
msCodepointToUnicode.put(i++, ch); msCodepointToUnicode.put(i++, ch);
} }
@ -586,7 +610,7 @@ public class StringUtil {
if (array == null || array.length == 0) return ""; if (array == null || array.length == 0) return "";
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(array[0]); sb.append(array[0]);
for (int i=1; i<array.length; i++) { for (int i = 1; i < array.length; i++) {
sb.append(separator).append(array[i]); sb.append(separator).append(array[i]);
} }
return sb.toString(); return sb.toString();
@ -619,7 +643,7 @@ public class StringUtil {
if (haystack == null) return 0; if (haystack == null) return 0;
int count = 0; int count = 0;
final int length = haystack.length(); final int length = haystack.length();
for (int i=0; i<length; i++) { for (int i = 0; i < length; i++) {
if (haystack.charAt(i) == needle) { if (haystack.charAt(i) == needle) {
count++; count++;
} }

View File

@ -29,6 +29,8 @@ import javax.xml.namespace.QName;
import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.StringUtil;
import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
@ -130,7 +132,7 @@ public final class XSSFPasswordHelper {
if (prefix == null || prefix.isEmpty()) { if (prefix == null || prefix.isEmpty()) {
return new QName(name); return new QName(name);
} else { } else {
return new QName(prefix+Character.toUpperCase(name.charAt(0))+name.substring(1)); return new QName(prefix + StringUtil.toUpperCase(name.charAt(0)) + name.substring(1));
} }
} }
} }

View File

@ -102,8 +102,10 @@ java.lang.Character#codePointAt(char[],int) @ Implicit end offset is error-prone
@defaultMessage specify a locale when using toUpperCase / to LowerCase @defaultMessage specify a locale when using toUpperCase / to LowerCase
#java.lang.Character#toLowerCase(char) java.lang.Character#isLowerCase(char)
#java.lang.Character#toUpperCase(char) java.lang.Character#isUpperCase(char)
java.lang.Character#toLowerCase(char)
java.lang.Character#toUpperCase(char)
java.lang.String#toLowerCase() java.lang.String#toLowerCase()
java.lang.String#toUpperCase() java.lang.String#toUpperCase()

View File

@ -18,6 +18,7 @@
package org.apache.poi.hwpf.dev; package org.apache.poi.hwpf.dev;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.poi.util.StringUtil;
/** /**
* Helper functions for the record transformations. Used during model classes * Helper functions for the record transformations. Used during model classes
@ -172,7 +173,7 @@ public class RecordUtil
{ {
StringBuilder fieldName = new StringBuilder(); StringBuilder fieldName = new StringBuilder();
toIdentifier( name, fieldName ); toIdentifier( name, fieldName );
fieldName.setCharAt( 0, Character.toUpperCase( fieldName.charAt( 0 ) ) ); fieldName.setCharAt( 0, toUpperCase( fieldName.charAt(0) ) );
pad( fieldName, padTo ); pad( fieldName, padTo );
return fieldName.toString(); return fieldName.toString();
@ -183,7 +184,7 @@ public class RecordUtil
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
result.append( type ); result.append( type );
result = pad( result, padTo ); result = pad( result, padTo );
result.setCharAt( 0, Character.toUpperCase( result.charAt( 0 ) ) ); result.setCharAt( 0, toUpperCase( result.charAt( 0 ) ) );
return result.toString(); return result.toString();
} }
@ -202,7 +203,7 @@ public class RecordUtil
if ( name.charAt( i ) == ' ' ) if ( name.charAt( i ) == ' ' )
fieldName.append( '_' ); fieldName.append( '_' );
else else
fieldName.append( Character.toUpperCase( name.charAt( i ) ) ); fieldName.append( toUpperCase( name.charAt( i ) ) );
} }
} }
@ -211,12 +212,16 @@ public class RecordUtil
for ( int i = 0; i < name.length(); i++ ) for ( int i = 0; i < name.length(); i++ )
{ {
if ( name.charAt( i ) == ' ' ) if ( name.charAt( i ) == ' ' )
fieldName.append( Character.toUpperCase( name.charAt( ++i ) ) ); fieldName.append( toUpperCase( name.charAt( ++i ) ) );
else else
fieldName.append( name.charAt( i ) ); fieldName.append( name.charAt( i ) );
} }
} }
private static char toUpperCase(char c) {
return StringUtil.toUpperCase(c).charAt(0);
}
public RecordUtil() public RecordUtil()
{ {
} }