Browse Source

Handling possible out-of-bounds exception when parsing RFC3966 format (#1690)

* Handling possible out-of-bounds exception that would be thrown in C++
and Java if a number with a phone-context tag is entered (RFC3966
format) but no actual phone context.
pull/1439/merge
lararennie 9 years ago
committed by GitHub
parent
commit
09519ab056
7 changed files with 42 additions and 6 deletions
  1. +3
    -2
      cpp/src/phonenumbers/phonenumberutil.cc
  2. +6
    -0
      cpp/test/phonenumbers/phonenumberutil_test.cc
  3. +3
    -2
      java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
  4. +11
    -0
      java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
  5. +3
    -1
      javascript/i18n/phonenumbers/phonenumberutil.js
  6. +13
    -0
      javascript/i18n/phonenumbers/phonenumberutil_test.js
  7. +3
    -1
      pending_code_changes.txt

+ 3
- 2
cpp/src/phonenumbers/phonenumberutil.cc View File

@ -2031,11 +2031,12 @@ void PhoneNumberUtil::BuildNationalNumberForParsing(
const string& number_to_parse, string* national_number) const {
size_t index_of_phone_context = number_to_parse.find(kRfc3966PhoneContext);
if (index_of_phone_context != string::npos) {
int phone_context_start =
size_t phone_context_start =
index_of_phone_context + strlen(kRfc3966PhoneContext);
// If the phone context contains a phone number prefix, we need to capture
// it, whereas domains will be ignored.
if (number_to_parse.at(phone_context_start) == kPlusSign[0]) {
if (phone_context_start < (number_to_parse.length() - 1) &&
number_to_parse.at(phone_context_start) == kPlusSign[0]) {
// Additional parameters might follow the phone context. If so, we will
// remove them here because the parameters after phone context are not
// important for parsing the phone number.


+ 6
- 0
cpp/test/phonenumbers/phonenumberutil_test.cc View File

@ -4023,6 +4023,12 @@ TEST_F(PhoneNumberUtilTest, FailedParseOnInvalidNumbers) {
phone_util_.Parse("tel:555-1234;phone-context=1-331",
RegionCode::ZZ(), &test_number));
EXPECT_EQ(PhoneNumber::default_instance(), test_number);
// Only the phone-context symbol is present, but no data.
EXPECT_EQ(PhoneNumberUtil::NOT_A_NUMBER,
phone_util_.Parse(";phone-context=",
RegionCode::ZZ(), &test_number));
EXPECT_EQ(PhoneNumber::default_instance(), test_number);
}
TEST_F(PhoneNumberUtilTest, ParseNumbersWithPlusWithNoRegion) {


+ 3
- 2
java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java View File

@ -3270,11 +3270,12 @@ public class PhoneNumberUtil {
*/
private void buildNationalNumberForParsing(String numberToParse, StringBuilder nationalNumber) {
int indexOfPhoneContext = numberToParse.indexOf(RFC3966_PHONE_CONTEXT);
if (indexOfPhoneContext > 0) {
if (indexOfPhoneContext >= 0) {
int phoneContextStart = indexOfPhoneContext + RFC3966_PHONE_CONTEXT.length();
// If the phone context contains a phone number prefix, we need to capture it, whereas domains
// will be ignored.
if (numberToParse.charAt(phoneContextStart) == PLUS_SIGN) {
if (phoneContextStart < (numberToParse.length() - 1)
&& numberToParse.charAt(phoneContextStart) == PLUS_SIGN) {
// Additional parameters might follow the phone context. If so, we will remove them here
// because the parameters after phone context are not important for parsing the
// phone number.


+ 11
- 0
java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java View File

@ -2508,6 +2508,17 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase {
NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
e.getErrorType());
}
try {
// Only the phone-context symbol is present, but no data.
String invalidRfcPhoneContext = ";phone-context=";
phoneUtil.parse(invalidRfcPhoneContext, RegionCode.ZZ);
fail("No number is present: should fail.");
} catch (NumberParseException e) {
// Expected this exception.
assertEquals("Wrong error type stored in exception.",
NumberParseException.ErrorType.NOT_A_NUMBER,
e.getErrorType());
}
}
public void testParseNumbersWithPlusWithNoRegion() throws Exception {


+ 3
- 1
javascript/i18n/phonenumbers/phonenumberutil.js View File

@ -4271,11 +4271,13 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.buildNationalNumberForParsing_ =
/** @type {number} */
var indexOfPhoneContext = numberToParse.indexOf(
i18n.phonenumbers.PhoneNumberUtil.RFC3966_PHONE_CONTEXT_);
if (indexOfPhoneContext > 0) {
if (indexOfPhoneContext >= 0) {
var phoneContextStart = indexOfPhoneContext +
i18n.phonenumbers.PhoneNumberUtil.RFC3966_PHONE_CONTEXT_.length;
// If the phone context contains a phone number prefix, we need to capture
// it, whereas domains will be ignored.
// No length check is necessary, as per C++ or Java, since out-of-bounds
// requests to charAt return an empty string.
if (numberToParse.charAt(phoneContextStart) ==
i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN) {
// Additional parameters might follow the phone context. If so, we will


+ 13
- 0
javascript/i18n/phonenumbers/phonenumberutil_test.js View File

@ -3217,6 +3217,19 @@ function testFailedParseOnInvalidNumbers() {
i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
e.message);
}
try {
// Only the phone-context symbol is present, but no data.
/** @type {string} */
var invalidRfcPhoneContext = ';phone-context=';
phoneUtil.parse(invalidRfcPhoneContext, RegionCode.ZZ);
fail('Should have thrown an exception, no valid country calling code ' +
'present.');
} catch (e) {
// Expected.
assertEquals('Wrong error type stored in exception.',
i18n.phonenumbers.Error.NOT_A_NUMBER,
e.message);
}
}
function testParseNumbersWithPlusWithNoRegion() {


+ 3
- 1
pending_code_changes.txt View File

@ -1 +1,3 @@
Code changes:
- Small fix for possible out-of-bounds exception on RFC3966 input where no
phone context was actually provided.

Loading…
Cancel
Save