d1b8c7cd1f
regular-expression processing: CVE-2007-4770/1: http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-4770 http://nvd.nist.gov/nvd.cfm?cvename=CVE-2007-4771 Bump PORTREVISION. PR: ports/120379 Submitted by: Tsurutani Naoki Since OpenOffice (mysteriously) continues to build its own version of ICU, its needs to be patched independently.
304 lines
11 KiB
Text
304 lines
11 KiB
Text
Index: /icu/branches/maint/maint-3-8/source/i18n/regexcmp.cpp
|
|
===================================================================
|
|
--- i18n/regexcmp.cpp (revision 21805)
|
|
+++ i18n/regexcmp.cpp (revision 23292)
|
|
@@ -3,5 +3,5 @@
|
|
// file: regexcmp.cpp
|
|
//
|
|
-// Copyright (C) 2002-2007 International Business Machines Corporation and others.
|
|
+// Copyright (C) 2002-2008 International Business Machines Corporation and others.
|
|
// All Rights Reserved.
|
|
//
|
|
@@ -1187,12 +1187,15 @@
|
|
// we fill the operand with the capture group number. At the end
|
|
// of compilation, it will be changed to the variable's location.
|
|
- U_ASSERT(groupNum > 0);
|
|
- int32_t op;
|
|
- if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
|
|
- op = URX_BUILD(URX_BACKREF_I, groupNum);
|
|
+ if (groupNum < 1) {
|
|
+ error(U_REGEX_INVALID_BACK_REF);
|
|
} else {
|
|
- op = URX_BUILD(URX_BACKREF, groupNum);
|
|
- }
|
|
- fRXPat->fCompiledPat->addElement(op, *fStatus);
|
|
+ int32_t op;
|
|
+ if (fModeFlags & UREGEX_CASE_INSENSITIVE) {
|
|
+ op = URX_BUILD(URX_BACKREF_I, groupNum);
|
|
+ } else {
|
|
+ op = URX_BUILD(URX_BACKREF, groupNum);
|
|
+ }
|
|
+ fRXPat->fCompiledPat->addElement(op, *fStatus);
|
|
+ }
|
|
}
|
|
break;
|
|
Index: /icu/branches/maint/maint-3-8/source/i18n/rematch.cpp
|
|
===================================================================
|
|
--- i18n/rematch.cpp (revision 21973)
|
|
+++ i18n/rematch.cpp (revision 23292)
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
**************************************************************************
|
|
-* Copyright (C) 2002-2007 International Business Machines Corporation *
|
|
+* Copyright (C) 2002-2008 International Business Machines Corporation *
|
|
* and others. All rights reserved. *
|
|
**************************************************************************
|
|
@@ -30,4 +30,13 @@
|
|
|
|
U_NAMESPACE_BEGIN
|
|
+
|
|
+// Limit the size of the back track stack, to avoid system failures caused
|
|
+// by heap exhaustion. Units are in 32 bit words, not bytes.
|
|
+// This value puts ICU's limits higher than most other regexp implementations,
|
|
+// which use recursion rather than the heap, and take more storage per
|
|
+// backtrack point.
|
|
+// This constant is _temporary_. Proper API to control the value will added.
|
|
+//
|
|
+static const int32_t BACKTRACK_STACK_CAPACITY = 8000000;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
@@ -54,6 +63,7 @@
|
|
if (fStack == NULL || fData == NULL) {
|
|
fDeferredStatus = U_MEMORY_ALLOCATION_ERROR;
|
|
- }
|
|
-
|
|
+ } else {
|
|
+ fStack->setMaxCapacity(BACKTRACK_STACK_CAPACITY);
|
|
+ }
|
|
reset(RegexStaticSets::gStaticSets->fEmptyString);
|
|
}
|
|
@@ -79,4 +89,6 @@
|
|
if (fStack == NULL || fData == NULL) {
|
|
status = U_MEMORY_ALLOCATION_ERROR;
|
|
+ } else {
|
|
+ fStack->setMaxCapacity(BACKTRACK_STACK_CAPACITY);
|
|
}
|
|
reset(input);
|
|
@@ -103,4 +115,6 @@
|
|
if (fStack == NULL || fData == NULL) {
|
|
status = U_MEMORY_ALLOCATION_ERROR;
|
|
+ } else {
|
|
+ fStack->setMaxCapacity(BACKTRACK_STACK_CAPACITY);
|
|
}
|
|
reset(RegexStaticSets::gStaticSets->fEmptyString);
|
|
@@ -1015,4 +1029,12 @@
|
|
// push storage for a new frame.
|
|
int32_t *newFP = fStack->reserveBlock(frameSize, status);
|
|
+ if (newFP == NULL) {
|
|
+ // Heap allocation error on attempted stack expansion.
|
|
+ // We need to return a writable stack frame, so just return the
|
|
+ // previous frame. The match operation will stop quickly
|
|
+ // becuase of the error status, after which the frame will never
|
|
+ // be looked at again.
|
|
+ return fp;
|
|
+ }
|
|
fp = (REStackFrame *)(newFP - frameSize); // in case of realloc of stack.
|
|
|
|
@@ -1030,6 +1052,6 @@
|
|
return (REStackFrame *)newFP;
|
|
}
|
|
-
|
|
-
|
|
+
|
|
+
|
|
//--------------------------------------------------------------------------------
|
|
//
|
|
@@ -2262,4 +2284,5 @@
|
|
|
|
if (U_FAILURE(status)) {
|
|
+ isMatch = FALSE;
|
|
break;
|
|
}
|
|
Index: /icu/branches/maint/maint-3-8/source/test/intltest/regextst.h
|
|
===================================================================
|
|
--- test/intltest/regextst.h (revision 22001)
|
|
+++ test/intltest/regextst.h (revision 23292)
|
|
@@ -1,5 +1,5 @@
|
|
/********************************************************************
|
|
* COPYRIGHT:
|
|
- * Copyright (c) 2002-2007, International Business Machines Corporation and
|
|
+ * Copyright (c) 2002-2008, International Business Machines Corporation and
|
|
* others. All Rights Reserved.
|
|
********************************************************************/
|
|
@@ -31,4 +31,5 @@
|
|
virtual void Errors();
|
|
virtual void PerlTests();
|
|
+ virtual void Bug6149();
|
|
|
|
// The following functions are internal to the regexp tests.
|
|
Index: /icu/branches/maint/maint-3-8/source/test/intltest/regextst.cpp
|
|
===================================================================
|
|
--- test/intltest/regextst.cpp (revision 22057)
|
|
+++ test/intltest/regextst.cpp (revision 23292)
|
|
@@ -1,5 +1,5 @@
|
|
/********************************************************************
|
|
* COPYRIGHT:
|
|
- * Copyright (c) 2002-2007, International Business Machines Corporation and
|
|
+ * Copyright (c) 2002-2008, International Business Machines Corporation and
|
|
* others. All Rights Reserved.
|
|
********************************************************************/
|
|
@@ -67,4 +67,8 @@
|
|
if (exec) PerlTests();
|
|
break;
|
|
+ case 7: name = "Bug 6149";
|
|
+ if (exec) Bug6149();
|
|
+ break;
|
|
+
|
|
|
|
|
|
@@ -1640,4 +1644,10 @@
|
|
// Ticket 5389
|
|
REGEX_ERR("*c", 1, 1, U_REGEX_RULE_SYNTAX);
|
|
+
|
|
+ // Invalid Back Reference \0
|
|
+ // For ICU 3.8 and earlier
|
|
+ // For ICU versions newer than 3.8, \0 introduces an octal escape.
|
|
+ //
|
|
+ REGEX_ERR("(ab)\\0", 1, 6, U_REGEX_INVALID_BACK_REF);
|
|
|
|
}
|
|
@@ -2123,4 +2133,24 @@
|
|
|
|
|
|
+//--------------------------------------------------------------
|
|
+//
|
|
+// Bug6149 Verify limits to heap expansion for backtrack stack.
|
|
+// Use this pattern,
|
|
+// "(a?){1,}"
|
|
+// The zero-length match will repeat forever.
|
|
+// (That this goes into a loop is another bug)
|
|
+//
|
|
+//---------------------------------------------------------------
|
|
+void RegexTest::Bug6149() {
|
|
+ UnicodeString pattern("(a?){1,}");
|
|
+ UnicodeString s("xyz");
|
|
+ uint32_t flags = 0;
|
|
+ UErrorCode status = U_ZERO_ERROR;
|
|
+
|
|
+ RegexMatcher matcher(pattern, s, flags, status);
|
|
+ UBool result = false;
|
|
+ REGEX_ASSERT_FAIL(result=matcher.matches(status), U_BUFFER_OVERFLOW_ERROR);
|
|
+ REGEX_ASSERT(result == FALSE);
|
|
+ }
|
|
|
|
#endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */
|
|
Index: /icu/branches/maint/maint-3-8/source/common/uvectr32.cpp
|
|
===================================================================
|
|
--- common/uvectr32.cpp (revision 12958)
|
|
+++ common/uvectr32.cpp (revision 23292)
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
******************************************************************************
|
|
-* Copyright (C) 1999-2003, International Business Machines Corporation and *
|
|
+* Copyright (C) 1999-2008, International Business Machines Corporation and *
|
|
* others. All Rights Reserved. *
|
|
******************************************************************************
|
|
@@ -27,4 +27,5 @@
|
|
count(0),
|
|
capacity(0),
|
|
+ maxCapacity(0),
|
|
elements(NULL)
|
|
{
|
|
@@ -35,4 +36,5 @@
|
|
count(0),
|
|
capacity(0),
|
|
+ maxCapacity(0),
|
|
elements(0)
|
|
{
|
|
@@ -46,4 +48,7 @@
|
|
if (initialCapacity < 1) {
|
|
initialCapacity = DEFUALT_CAPACITY;
|
|
+ }
|
|
+ if (maxCapacity>0 && maxCapacity<initialCapacity) {
|
|
+ initialCapacity = maxCapacity;
|
|
}
|
|
elements = (int32_t *)uprv_malloc(sizeof(int32_t)*initialCapacity);
|
|
@@ -190,19 +195,33 @@
|
|
if (capacity >= minimumCapacity) {
|
|
return TRUE;
|
|
- } else {
|
|
- int32_t newCap = capacity * 2;
|
|
- if (newCap < minimumCapacity) {
|
|
- newCap = minimumCapacity;
|
|
- }
|
|
- int32_t* newElems = (int32_t *)uprv_malloc(sizeof(int32_t)*newCap);
|
|
- if (newElems == 0) {
|
|
- status = U_MEMORY_ALLOCATION_ERROR;
|
|
- return FALSE;
|
|
- }
|
|
- uprv_memcpy(newElems, elements, sizeof(elements[0]) * count);
|
|
- uprv_free(elements);
|
|
- elements = newElems;
|
|
- capacity = newCap;
|
|
- return TRUE;
|
|
+ }
|
|
+ if (maxCapacity>0 && minimumCapacity>maxCapacity) {
|
|
+ status = U_BUFFER_OVERFLOW_ERROR;
|
|
+ return FALSE;
|
|
+ }
|
|
+ int32_t newCap = capacity * 2;
|
|
+ if (newCap < minimumCapacity) {
|
|
+ newCap = minimumCapacity;
|
|
+ }
|
|
+ if (maxCapacity > 0 && newCap > maxCapacity) {
|
|
+ newCap = maxCapacity;
|
|
+ }
|
|
+ int32_t* newElems = (int32_t *)uprv_malloc(sizeof(int32_t)*newCap);
|
|
+ if (newElems == 0) {
|
|
+ status = U_MEMORY_ALLOCATION_ERROR;
|
|
+ return FALSE;
|
|
+ }
|
|
+ uprv_memcpy(newElems, elements, sizeof(elements[0]) * count);
|
|
+ uprv_free(elements);
|
|
+ elements = newElems;
|
|
+ capacity = newCap;
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+void UVector32::setMaxCapacity(int32_t limit) {
|
|
+ U_ASSERT(limit >= 0);
|
|
+ maxCapacity = limit;
|
|
+ if (maxCapacity < 0) {
|
|
+ maxCapacity = 0;
|
|
}
|
|
}
|
|
Index: /icu/branches/maint/maint-3-8/source/common/uvectr32.h
|
|
===================================================================
|
|
--- common/uvectr32.h (revision 19000)
|
|
+++ common/uvectr32.h (revision 23292)
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
**********************************************************************
|
|
-* Copyright (C) 1999-2006, International Business Machines
|
|
+* Copyright (C) 1999-2008, International Business Machines
|
|
* Corporation and others. All Rights Reserved.
|
|
**********************************************************************
|
|
@@ -62,4 +62,6 @@
|
|
|
|
int32_t capacity;
|
|
+
|
|
+ int32_t maxCapacity; // Limit beyond which capacity is not permitted to grow.
|
|
|
|
int32_t* elements;
|
|
@@ -161,4 +163,12 @@
|
|
*/
|
|
int32_t *getBuffer() const;
|
|
+
|
|
+ /**
|
|
+ * Set the maximum allowed buffer capacity for this vector/stack.
|
|
+ * Default with no limit set is unlimited, go until malloc() fails.
|
|
+ * A Limit of zero means unlimited capacity.
|
|
+ * Units are vector elements (32 bits each), not bytes.
|
|
+ */
|
|
+ void setMaxCapacity(int32_t limit);
|
|
|
|
/**
|
|
@@ -222,5 +232,7 @@
|
|
|
|
inline int32_t *UVector32::reserveBlock(int32_t size, UErrorCode &status) {
|
|
- ensureCapacity(count+size, status);
|
|
+ if (ensureCapacity(count+size, status) == FALSE) {
|
|
+ return NULL;
|
|
+ }
|
|
int32_t *rp = elements+count;
|
|
count += size;
|