ICU-13503 declare variable-length array at end of struct with length 1 to disable bounds checkers
X-SVN-Rev: 40736
This commit is contained in:
parent
3bbf68ff4e
commit
27f8d70bcd
@ -867,9 +867,7 @@ int32_t RuleBasedBreakIterator::handleNext() {
|
|||||||
// State Transition - move machine to its next state
|
// State Transition - move machine to its next state
|
||||||
//
|
//
|
||||||
|
|
||||||
// Note: fNextState is defined as uint16_t[2], but we are casting
|
// fNextState is a variable-length array.
|
||||||
// a generated RBBI table to RBBIStateTableRow and some tables
|
|
||||||
// actually have more than 2 categories.
|
|
||||||
U_ASSERT(category<fData->fHeader->fCatCount);
|
U_ASSERT(category<fData->fHeader->fCatCount);
|
||||||
state = row->fNextState[category]; /*Not accessing beyond memory*/
|
state = row->fNextState[category]; /*Not accessing beyond memory*/
|
||||||
row = (RBBIStateTableRow *)
|
row = (RBBIStateTableRow *)
|
||||||
@ -1041,9 +1039,7 @@ int32_t RuleBasedBreakIterator::handlePrevious(int32_t fromPosition) {
|
|||||||
// State Transition - move machine to its next state
|
// State Transition - move machine to its next state
|
||||||
//
|
//
|
||||||
|
|
||||||
// Note: fNextState is defined as uint16_t[2], but we are casting
|
// fNextState is a variable-length array.
|
||||||
// a generated RBBI table to RBBIStateTableRow and some tables
|
|
||||||
// actually have more than 2 categories.
|
|
||||||
U_ASSERT(category<fData->fHeader->fCatCount);
|
U_ASSERT(category<fData->fHeader->fCatCount);
|
||||||
state = row->fNextState[category]; /*Not accessing beyond memory*/
|
state = row->fNextState[category]; /*Not accessing beyond memory*/
|
||||||
row = (RBBIStateTableRow *)
|
row = (RBBIStateTableRow *)
|
||||||
|
@ -116,9 +116,10 @@ struct RBBIStateTableRow {
|
|||||||
/* StatusTable of the set of matching */
|
/* StatusTable of the set of matching */
|
||||||
/* tags (rule status values) */
|
/* tags (rule status values) */
|
||||||
int16_t fReserved;
|
int16_t fReserved;
|
||||||
uint16_t fNextState[2]; /* Next State, indexed by char category. */
|
uint16_t fNextState[1]; /* Next State, indexed by char category. */
|
||||||
/* This array does not have two elements */
|
/* Variable-length array declared with length 1 */
|
||||||
/* Array Size is actually fData->fHeader->fCatCount */
|
/* to disable bounds checkers. */
|
||||||
|
/* Array Size is actually fData->fHeader->fCatCount*/
|
||||||
/* CAUTION: see RBBITableBuilder::getTableSize() */
|
/* CAUTION: see RBBITableBuilder::getTableSize() */
|
||||||
/* before changing anything here. */
|
/* before changing anything here. */
|
||||||
};
|
};
|
||||||
@ -129,7 +130,9 @@ struct RBBIStateTable {
|
|||||||
uint32_t fRowLen; /* Length of a state table row, in bytes. */
|
uint32_t fRowLen; /* Length of a state table row, in bytes. */
|
||||||
uint32_t fFlags; /* Option Flags for this state table */
|
uint32_t fFlags; /* Option Flags for this state table */
|
||||||
uint32_t fReserved; /* reserved */
|
uint32_t fReserved; /* reserved */
|
||||||
char fTableData[4]; /* First RBBIStateTableRow begins here. */
|
char fTableData[1]; /* First RBBIStateTableRow begins here. */
|
||||||
|
/* Variable-length array declared with length 1 */
|
||||||
|
/* to disable bounds checkers. */
|
||||||
/* (making it char[] simplifies ugly address */
|
/* (making it char[] simplifies ugly address */
|
||||||
/* arithmetic for indexing variable length rows.) */
|
/* arithmetic for indexing variable length rows.) */
|
||||||
};
|
};
|
||||||
|
@ -1095,15 +1095,12 @@ int32_t RBBITableBuilder::getTableSize() const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = sizeof(RBBIStateTable) - 4; // The header, with no rows to the table.
|
size = offsetof(RBBIStateTable, fTableData); // The header, with no rows to the table.
|
||||||
|
|
||||||
numRows = fDStates->size();
|
numRows = fDStates->size();
|
||||||
numCols = fRB->fSetBuilder->getNumCharCategories();
|
numCols = fRB->fSetBuilder->getNumCharCategories();
|
||||||
|
|
||||||
// Note The declaration of RBBIStateTableRow is for a table of two columns.
|
rowSize = offsetof(RBBIStateTableRow, fNextState) + sizeof(uint16_t)*numCols;
|
||||||
// Therefore we subtract two from numCols when determining
|
|
||||||
// how much storage to add to a row for the total columns.
|
|
||||||
rowSize = sizeof(RBBIStateTableRow) + sizeof(uint16_t)*(numCols-2);
|
|
||||||
size += numRows * rowSize;
|
size += numRows * rowSize;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -1126,14 +1123,14 @@ void RBBITableBuilder::exportTable(void *where) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fRB->fSetBuilder->getNumCharCategories() > 0x7fff ||
|
int32_t catCount = fRB->fSetBuilder->getNumCharCategories();
|
||||||
|
if (catCount > 0x7fff ||
|
||||||
fDStates->size() > 0x7fff) {
|
fDStates->size() > 0x7fff) {
|
||||||
*fStatus = U_BRK_INTERNAL_ERROR;
|
*fStatus = U_BRK_INTERNAL_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
table->fRowLen = sizeof(RBBIStateTableRow) +
|
table->fRowLen = offsetof(RBBIStateTableRow, fNextState) + sizeof(uint16_t) * catCount;
|
||||||
sizeof(uint16_t) * (fRB->fSetBuilder->getNumCharCategories() - 2);
|
|
||||||
table->fNumStates = fDStates->size();
|
table->fNumStates = fDStates->size();
|
||||||
table->fFlags = 0;
|
table->fFlags = 0;
|
||||||
if (fRB->fLookAheadHardBreak) {
|
if (fRB->fLookAheadHardBreak) {
|
||||||
@ -1152,7 +1149,7 @@ void RBBITableBuilder::exportTable(void *where) {
|
|||||||
row->fAccepting = (int16_t)sd->fAccepting;
|
row->fAccepting = (int16_t)sd->fAccepting;
|
||||||
row->fLookAhead = (int16_t)sd->fLookAhead;
|
row->fLookAhead = (int16_t)sd->fLookAhead;
|
||||||
row->fTagIdx = (int16_t)sd->fTagsIdx;
|
row->fTagIdx = (int16_t)sd->fTagsIdx;
|
||||||
for (col=0; col<fRB->fSetBuilder->getNumCharCategories(); col++) {
|
for (col=0; col<catCount; col++) {
|
||||||
row->fNextState[col] = (uint16_t)sd->fDtran->elementAti(col);
|
row->fNextState[col] = (uint16_t)sd->fDtran->elementAti(col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,11 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
uint32_t reserved;
|
uint32_t reserved;
|
||||||
PointerTOCEntry entry[2]; /* Actual size is from count. */
|
/**
|
||||||
|
* Variable-length array declared with length 1 to disable bounds checkers.
|
||||||
|
* The actual array length is in the count field.
|
||||||
|
*/
|
||||||
|
PointerTOCEntry entry[1];
|
||||||
} PointerTOC;
|
} PointerTOC;
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +52,11 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
UDataOffsetTOCEntry entry[2]; /* Actual size of array is from count. */
|
/**
|
||||||
|
* Variable-length array declared with length 1 to disable bounds checkers.
|
||||||
|
* The actual array length is in the count field.
|
||||||
|
*/
|
||||||
|
UDataOffsetTOCEntry entry[1];
|
||||||
} UDataOffsetTOC;
|
} UDataOffsetTOC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,10 +50,12 @@ static void syntaxError(const UnicodeString& pattern,
|
|||||||
parseError.preContext[stop-start] = 0;
|
parseError.preContext[stop-start] = 0;
|
||||||
|
|
||||||
//for post-context
|
//for post-context
|
||||||
start = pos+1;
|
start = pattern.moveIndex32(pos, 1);
|
||||||
stop = ((pos+U_PARSE_CONTEXT_LEN)<=pattern.length()) ? (pos+(U_PARSE_CONTEXT_LEN-1)) :
|
stop = pos + U_PARSE_CONTEXT_LEN - 1;
|
||||||
pattern.length();
|
if (stop > pattern.length()) {
|
||||||
pattern.extract(start,stop-start,parseError.postContext,0);
|
stop = pattern.length();
|
||||||
|
}
|
||||||
|
pattern.extract(start, stop - start, parseError.postContext, 0);
|
||||||
//null terminate the buffer
|
//null terminate the buffer
|
||||||
parseError.postContext[stop-start]= 0;
|
parseError.postContext[stop-start]= 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user