diff options
author | Tammo Spalink <tammo@google.com> | 2009-06-25 16:13:51 +0800 |
---|---|---|
committer | Tammo Spalink <tammo@google.com> | 2009-06-29 12:51:22 +0800 |
commit | 3a08cec99e104f74f28ba2463f00c8d4e6d1967e (patch) | |
tree | a326d7de10c17acce6d1a37f51913de491cff307 | |
parent | 9171749700853305f3e6abbcdbd9e02f3a71d459 (diff) | |
download | frameworks_base-3a08cec99e104f74f28ba2463f00c8d4e6d1967e.zip frameworks_base-3a08cec99e104f74f28ba2463f00c8d4e6d1967e.tar.gz frameworks_base-3a08cec99e104f74f28ba2463f00c8d4e6d1967e.tar.bz2 |
fix potential string index problems in PhoneNumberUtils.numberToCalledPartyBCDHelper
addresses http://buganizer/issue?id=1489784
-rw-r--r-- | telephony/java/android/telephony/PhoneNumberUtils.java | 105 | ||||
-rw-r--r-- | tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java | 7 |
2 files changed, 53 insertions, 59 deletions
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index d3942fc..dbe8431 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -701,17 +701,6 @@ public class PhoneNumberUtils } /** - * Note: calls extractNetworkPortion(), so do not use for - * SIM EF[ADN] style records - * - * Exceptions thrown if extractNetworkPortion(s).length() == 0 - */ - public static byte[] - networkPortionToCalledPartyBCD(String s) { - return numberToCalledPartyBCD(extractNetworkPortion(s)); - } - - /** * Return true iff the network portion of <code>address</code> is, * as far as we can tell on the device, suitable for use as an SMS * destination address. @@ -744,12 +733,25 @@ public class PhoneNumberUtils } /** + * Note: calls extractNetworkPortion(), so do not use for + * SIM EF[ADN] style records + * + * Returns null if network portion is empty. + */ + public static byte[] + networkPortionToCalledPartyBCD(String s) { + String networkPortion = extractNetworkPortion(s); + return numberToCalledPartyBCDHelper(networkPortion, false); + } + + /** * Same as {@link #networkPortionToCalledPartyBCD}, but includes a * one-byte length prefix. */ public static byte[] networkPortionToCalledPartyBCDWithLength(String s) { - return numberToCalledPartyBCDWithLength(extractNetworkPortion(s)); + String networkPortion = extractNetworkPortion(s); + return numberToCalledPartyBCDHelper(networkPortion, true); } /** @@ -761,61 +763,46 @@ public class PhoneNumberUtils */ public static byte[] numberToCalledPartyBCD(String number) { - // The extra byte required for '+' is taken into consideration while calculating - // length of ret. - int size = (hasPlus(number) ? number.length() - 1 : number.length()); - byte[] ret = new byte[(size + 1) / 2 + 1]; - - return numberToCalledPartyBCDHelper(ret, 0, number); + return numberToCalledPartyBCDHelper(number, false); } /** - * Same as {@link #numberToCalledPartyBCD}, but includes a - * one-byte length prefix. + * If includeLength is true, prepend a one-byte length value to + * the return array. */ private static byte[] - numberToCalledPartyBCDWithLength(String number) { - // The extra byte required for '+' is taken into consideration while calculating - // length of ret. - int size = (hasPlus(number) ? number.length() - 1 : number.length()); - int length = (size + 1) / 2 + 1; - byte[] ret = new byte[length + 1]; - - ret[0] = (byte) (length & 0xff); - return numberToCalledPartyBCDHelper(ret, 1, number); - } - - private static boolean - hasPlus(String s) { - return s.indexOf('+') >= 0; - } - - private static byte[] - numberToCalledPartyBCDHelper(byte[] ret, int offset, String number) { - if (hasPlus(number)) { - number = number.replaceAll("\\+", ""); - ret[offset] = (byte) TOA_International; - } else { - ret[offset] = (byte) TOA_Unknown; + numberToCalledPartyBCDHelper(String number, boolean includeLength) { + int numberLenReal = number.length(); + int numberLenEffective = numberLenReal; + boolean hasPlus = number.indexOf('+') != -1; + if (hasPlus) numberLenEffective--; + + if (numberLenEffective == 0) return null; + + int resultLen = (numberLenEffective + 1) / 2; // Encoded numbers require only 4 bits each. + int extraBytes = 1; // Prepended TOA byte. + if (includeLength) extraBytes++; // Optional prepended length byte. + resultLen += extraBytes; + + byte[] result = new byte[resultLen]; + + int digitCount = 0; + for (int i = 0; i < numberLenReal; i++) { + char c = number.charAt(i); + if (c == '+') continue; + int shift = ((digitCount & 0x01) == 1) ? 4 : 0; + result[extraBytes + (digitCount >> 1)] |= (byte)((charToBCD(c) & 0x0F) << shift); + digitCount++; } - int size = number.length(); - int curChar = 0; - int countFullBytes = ret.length - offset - 1 - ((size - curChar) & 1); - for (int i = 1; i < 1 + countFullBytes; i++) { - ret[offset + i] - = (byte) ((charToBCD(number.charAt(curChar++))) - | (charToBCD(number.charAt(curChar++))) << 4); - } + // 1-fill any trailing odd nibble/quartet. + if ((digitCount & 0x01) == 1) result[extraBytes + (digitCount >> 1)] |= 0xF0; - // The left-over octet for odd-length phone numbers should be - // filled with 0xf. - if (countFullBytes + offset < ret.length - 1) { - ret[ret.length - 1] - = (byte) (charToBCD(number.charAt(curChar)) - | (0xf << 4)); - } - return ret; + int offset = 0; + if (includeLength) result[offset++] = (byte)(resultLen - 1); + result[offset] = (byte)(hasPlus ? TOA_International : TOA_Unknown); + + return result; } /** all of 'a' up to len must match non-US trunk prefix ('0') */ diff --git a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java index e8bd239..577d384 100644 --- a/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java +++ b/tests/CoreTests/com/android/internal/telephony/PhoneNumberUtilsTest.java @@ -93,6 +93,13 @@ public class PhoneNumberUtilsTest extends TestCase { assertEquals(b[i], bRet[i]); } + bRet = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength("+17005550020"); + assertEquals(8, bRet.length); + assertEquals(bRet[0], 7); + for (int i = 1; i < 8; i++) { + assertEquals(b[i - 1], bRet[i]); + } + bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("7005550020"); assertEquals("7005550020", PhoneNumberUtils.calledPartyBCDToString(bRet, 0, bRet.length)); |