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)); | 
