Merge change 5359 into donut

* changes:
  fix potential string index problems in PhoneNumberUtils.numberToCalledPartyBCDHelper
This commit is contained in:
Android (Google) Code Review
2009-06-29 19:22:05 -07:00
2 changed files with 50 additions and 56 deletions

View File

@ -700,17 +700,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, * 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 * as far as we can tell on the device, suitable for use as an SMS
@ -743,13 +732,26 @@ public class PhoneNumberUtils
return true; return true;
} }
/**
* 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 * Same as {@link #networkPortionToCalledPartyBCD}, but includes a
* one-byte length prefix. * one-byte length prefix.
*/ */
public static byte[] public static byte[]
networkPortionToCalledPartyBCDWithLength(String s) { 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[] public static byte[]
numberToCalledPartyBCD(String number) { numberToCalledPartyBCD(String number) {
// The extra byte required for '+' is taken into consideration while calculating return numberToCalledPartyBCDHelper(number, false);
// 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);
} }
/** /**
* Same as {@link #numberToCalledPartyBCD}, but includes a * If includeLength is true, prepend a one-byte length value to
* one-byte length prefix. * the return array.
*/ */
private static byte[] private static byte[]
numberToCalledPartyBCDWithLength(String number) { numberToCalledPartyBCDHelper(String number, boolean includeLength) {
// The extra byte required for '+' is taken into consideration while calculating int numberLenReal = number.length();
// length of ret. int numberLenEffective = numberLenReal;
int size = (hasPlus(number) ? number.length() - 1 : number.length()); boolean hasPlus = number.indexOf('+') != -1;
int length = (size + 1) / 2 + 1; if (hasPlus) numberLenEffective--;
byte[] ret = new byte[length + 1];
ret[0] = (byte) (length & 0xff); if (numberLenEffective == 0) return null;
return numberToCalledPartyBCDHelper(ret, 1, number);
}
private static boolean int resultLen = (numberLenEffective + 1) / 2; // Encoded numbers require only 4 bits each.
hasPlus(String s) { int extraBytes = 1; // Prepended TOA byte.
return s.indexOf('+') >= 0; if (includeLength) extraBytes++; // Optional prepended length byte.
} resultLen += extraBytes;
private static byte[] byte[] result = new byte[resultLen];
numberToCalledPartyBCDHelper(byte[] ret, int offset, String number) {
if (hasPlus(number)) { int digitCount = 0;
number = number.replaceAll("\\+", ""); for (int i = 0; i < numberLenReal; i++) {
ret[offset] = (byte) TOA_International; char c = number.charAt(i);
} else { if (c == '+') continue;
ret[offset] = (byte) TOA_Unknown; int shift = ((digitCount & 0x01) == 1) ? 4 : 0;
result[extraBytes + (digitCount >> 1)] |= (byte)((charToBCD(c) & 0x0F) << shift);
digitCount++;
} }
int size = number.length(); // 1-fill any trailing odd nibble/quartet.
int curChar = 0; if ((digitCount & 0x01) == 1) result[extraBytes + (digitCount >> 1)] |= 0xF0;
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);
}
// The left-over octet for odd-length phone numbers should be int offset = 0;
// filled with 0xf. if (includeLength) result[offset++] = (byte)(resultLen - 1);
if (countFullBytes + offset < ret.length - 1) { result[offset] = (byte)(hasPlus ? TOA_International : TOA_Unknown);
ret[ret.length - 1]
= (byte) (charToBCD(number.charAt(curChar)) return result;
| (0xf << 4));
}
return ret;
} }
/** all of 'a' up to len must match non-US trunk prefix ('0') */ /** all of 'a' up to len must match non-US trunk prefix ('0') */

View File

@ -93,6 +93,13 @@ public class PhoneNumberUtilsTest extends TestCase {
assertEquals(b[i], bRet[i]); 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"); bRet = PhoneNumberUtils.networkPortionToCalledPartyBCD("7005550020");
assertEquals("7005550020", assertEquals("7005550020",
PhoneNumberUtils.calledPartyBCDToString(bRet, 0, bRet.length)); PhoneNumberUtils.calledPartyBCDToString(bRet, 0, bRet.length));