• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Index: source/test/cintltst/cbiditst.c
2===================================================================
3--- source/test/cintltst/cbiditst.c	(revision 36303)
4+++ source/test/cintltst/cbiditst.c	(revision 36304)
5@@ -87,6 +87,8 @@
6
7 static void doTailTest(void);
8
9+static void testBracketOverflow(void);
10+
11 /* new BIDI API */
12 static void testReorderingMode(void);
13 static void testReorderRunsOnly(void);
14@@ -133,6 +135,7 @@
15     addTest(root, testClassOverride, "complex/bidi/TestClassOverride");
16     addTest(root, testGetBaseDirection, "complex/bidi/testGetBaseDirection");
17     addTest(root, testContext, "complex/bidi/testContext");
18+    addTest(root, testBracketOverflow, "complex/bidi/TestBracketOverflow");
19
20     addTest(root, doArabicShapingTest, "complex/arabic-shaping/ArabicShapingTest");
21     addTest(root, doLamAlefSpecialVLTRArabicShapingTest, "complex/arabic-shaping/lamalef");
22@@ -4896,3 +4899,25 @@
23
24     log_verbose("\nExiting TestContext \n\n");
25 }
26+
27+/* Ticket#11054 ubidi_setPara crash with heavily nested brackets */
28+static void
29+testBracketOverflow(void) {
30+    static const char* TEXT = "(((((((((((((((((((((((((((((((((((((((((a)(A)))))))))))))))))))))))))))))))))))))))))";
31+    UErrorCode status = U_ZERO_ERROR;
32+    UBiDi* bidi;
33+    UChar src[100];
34+    UChar dest[100];
35+    int32_t len;
36+
37+    bidi = ubidi_open();
38+    len = uprv_strlen(TEXT);
39+    pseudoToU16(len, TEXT, src);
40+    ubidi_setPara(bidi, src, len, UBIDI_DEFAULT_LTR , NULL, &status);
41+    if (U_FAILURE(status)) {
42+        log_err("setPara failed with heavily nested brackets - %s", u_errorName(status));
43+    }
44+
45+    ubidi_close(bidi);
46+}
47+
48Index: source/common/ubidiimp.h
49===================================================================
50--- source/common/ubidiimp.h	(revision 36303)
51+++ source/common/ubidiimp.h	(revision 36304)
52@@ -173,7 +173,7 @@
53     /* array of opening entries which should be enough in most cases; no malloc() */
54     Opening simpleOpenings[SIMPLE_OPENINGS_SIZE];
55     Opening *openings;                  /* pointer to current array of entries */
56-    int32_t openingsSize;               /* number of allocated entries */
57+    int32_t openingsCount;              /* number of allocated entries */
58     int32_t isoRunLast;                 /* index of last used entry */
59     /* array of nested isolated sequence entries; can never excess UBIDI_MAX_EXPLICIT_LEVEL
60        + 1 for index 0, + 1 for before the first isolated sequence */
61Index: source/common/ubidi.c
62===================================================================
63--- source/common/ubidi.c	(revision 36303)
64+++ source/common/ubidi.c	(revision 36304)
65@@ -679,10 +679,10 @@
66     bd->isoRuns[0].contextPos=0;
67     if(pBiDi->openingsMemory) {
68         bd->openings=pBiDi->openingsMemory;
69-        bd->openingsSize=pBiDi->openingsSize;
70+        bd->openingsCount=pBiDi->openingsSize / sizeof(Opening);
71     } else {
72         bd->openings=bd->simpleOpenings;
73-        bd->openingsSize=SIMPLE_OPENINGS_SIZE;
74+        bd->openingsCount=SIMPLE_OPENINGS_SIZE;
75     }
76     bd->isNumbersSpecial=bd->pBiDi->reorderingMode==UBIDI_REORDER_NUMBERS_SPECIAL ||
77                          bd->pBiDi->reorderingMode==UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL;
78@@ -743,7 +743,7 @@
79 bracketAddOpening(BracketData *bd, UChar match, int32_t position) {
80     IsoRun *pLastIsoRun=&bd->isoRuns[bd->isoRunLast];
81     Opening *pOpening;
82-    if(pLastIsoRun->limit>=bd->openingsSize) {  /* no available new entry */
83+    if(pLastIsoRun->limit>=bd->openingsCount) {  /* no available new entry */
84         UBiDi *pBiDi=bd->pBiDi;
85         if(!getInitialOpeningsMemory(pBiDi, pLastIsoRun->limit * 2))
86             return FALSE;
87@@ -751,7 +751,7 @@
88             uprv_memcpy(pBiDi->openingsMemory, bd->simpleOpenings,
89                         SIMPLE_OPENINGS_SIZE * sizeof(Opening));
90         bd->openings=pBiDi->openingsMemory;     /* may have changed */
91-        bd->openingsSize=pBiDi->openingsSize;
92+        bd->openingsCount=pBiDi->openingsSize / sizeof(Opening);
93     }
94     pOpening=&bd->openings[pLastIsoRun->limit];
95     pOpening->position=position;
96