From d170952252555d22eb926bf9c40c40ef0bfcdb51 Mon Sep 17 00:00:00 2001 From: George Rhoten Date: Fri, 1 Feb 2008 07:08:13 +0000 Subject: [PATCH] ICU-6165 Prevent a reading past the end of a buffer. X-SVN-Rev: 23340 --- icu4c/source/i18n/csr2022.cpp | 25 ++++++++------ icu4c/source/test/cintltst/ucsdetst.c | 49 +++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/icu4c/source/i18n/csr2022.cpp b/icu4c/source/i18n/csr2022.cpp index c7165f1c0d3..68e5ff61fde 100644 --- a/icu4c/source/i18n/csr2022.cpp +++ b/icu4c/source/i18n/csr2022.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 2005-2006, International Business Machines + * Copyright (C) 2005-2008, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** */ @@ -43,21 +43,24 @@ int32_t CharsetRecog_2022::match_2022(const uint8_t *text, int32_t textLen, cons if(text[i] == 0x1B) { escN = 0; while(escN < escapeSequences_length) { - int32_t seq_length = uprv_strlen((const char *) escapeSequences[escN]); const uint8_t *seq = escapeSequences[escN]; + int32_t seq_length = uprv_strlen((const char *) seq); - j = 1; - while(j < seq_length) { - if(seq[j] != text[i+j]) { - goto checkEscapes; + if (textLen-i >= seq_length) { + j = 1; + while(j < seq_length) { + if(seq[j] != text[i+j]) { + goto checkEscapes; + } + + j += 1; } - j += 1; + hits += 1; + i += seq_length-1; + goto scanInput; } - - hits += 1; - i += seq_length-1; - goto scanInput; + // else we ran out of string to compare this time. checkEscapes: escN += 1; } diff --git a/icu4c/source/test/cintltst/ucsdetst.c b/icu4c/source/test/cintltst/ucsdetst.c index 9bc18d329ea..c1a491dc1f2 100644 --- a/icu4c/source/test/cintltst/ucsdetst.c +++ b/icu4c/source/test/cintltst/ucsdetst.c @@ -1,6 +1,6 @@ /* **************************************************************************** - * Copyright (c) 2005-2006, International Business Machines Corporation and * + * Copyright (c) 2005-2008, International Business Machines Corporation and * * others. All Rights Reserved. * **************************************************************************** */ @@ -16,7 +16,7 @@ #include #include -#define ARRAY_SIZE(array) (sizeof array / sizeof array[0]) +#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) #define NEW_ARRAY(type,count) (type *) malloc((count) * sizeof(type)) #define DELETE_ARRAY(array) free(array) @@ -27,6 +27,7 @@ static void TestUTF16(void); static void TestC1Bytes(void); static void TestInputFilter(void); static void TestChaining(void); +static void TestBufferOverflow(void); void addUCsdetTest(TestNode** root); @@ -38,6 +39,7 @@ void addUCsdetTest(TestNode** root) addTest(root, &TestC1Bytes, "ucsdetst/TestC1Bytes"); addTest(root, &TestInputFilter, "ucsdetst/TestInputFilter"); addTest(root, &TestChaining, "ucsdetst/TestErrorChaining"); + addTest(root, &TestBufferOverflow, "ucsdetst/TestBufferOverflow"); } static int32_t preflight(const UChar *src, int32_t length, UConverter *cnv) @@ -353,3 +355,46 @@ static void TestChaining(void) { log_err("Status got changed to %s\n", u_errorName(status)); } } + +static void TestBufferOverflow(void) { + UErrorCode status = U_ZERO_ERROR; + static const char *testStrings[] = { + "\x80 This is English \x1b", /* A partial ISO-2022 shift state at the end */ + "\x80 This is English \x1b\x24", /* A partial ISO-2022 shift state at the end */ + "\x80 This is English \x1b\x24\x28", /* A partial ISO-2022 shift state at the end */ + "\x80 This is English \x1b\x24\x28\x44", /* A complete ISO-2022 shift state at the end with a bad one at the start */ + "\x1b\x24\x28\x44" /* A complete ISO-2022 shift state at the end */ + }; + static const char *testResults[] = { + "windows-1252", + "windows-1252", + "windows-1252", + "windows-1252", + "ISO-2022-JP" + }; + int32_t idx = 0; + UCharsetDetector *csd = ucsdet_open(&status); + const UCharsetMatch *match; + + ucsdet_setDeclaredEncoding(csd, "ISO-2022-JP", -1, &status); + + if (U_FAILURE(status)) { + log_err("Couldn't open detector. %s\n", u_errorName(status)); + goto bail; + } + + for (idx = 0; idx < ARRAY_SIZE(testStrings); idx++) { + ucsdet_setText(csd, testStrings[idx], -1, &status); + match = ucsdet_detect(csd, &status); + + if (strcmp(ucsdet_getName(match, &status), testResults[idx]) != 0) { + log_err("Unexpectedly got %s instead of %s at index %d with confidence %d.\n", + ucsdet_getName(match, &status), testResults[idx], idx, ucsdet_getConfidence(match, &status)); + goto bail; + } + } + +bail: + ucsdet_close(csd); +} +