1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-30 22:43:14 +03:00

Check for overflow when allocating two-dimensional arrays

Found by lgtm.com
This commit is contained in:
Nick Wellnhofer
2020-01-02 14:45:28 +01:00
parent 9bd7abfba4
commit 52649b63eb

View File

@ -26,6 +26,9 @@
#ifdef HAVE_LIMITS_H #ifdef HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#endif #endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <libxml/tree.h> #include <libxml/tree.h>
#include <libxml/parserInternals.h> #include <libxml/parserInternals.h>
@ -36,6 +39,9 @@
#ifndef INT_MAX #ifndef INT_MAX
#define INT_MAX 123456789 /* easy to flag and big enough for our needs */ #define INT_MAX 123456789 /* easy to flag and big enough for our needs */
#endif #endif
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t) -1)
#endif
/* #define DEBUG_REGEXP_GRAPH */ /* #define DEBUG_REGEXP_GRAPH */
/* #define DEBUG_REGEXP_EXEC */ /* #define DEBUG_REGEXP_EXEC */
@ -418,6 +424,32 @@ xmlRegexpErrCompile(xmlRegParserCtxtPtr ctxt, const char *extra)
************************************************************************/ ************************************************************************/
static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt); static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt);
/**
* xmlRegCalloc2:
* @dim1: size of first dimension
* @dim2: size of second dimension
* @elemSize: size of element
*
* Allocate a two-dimensional array and set all elements to zero.
*
* Returns the new array or NULL in case of error.
*/
static void*
xmlRegCalloc2(size_t dim1, size_t dim2, size_t elemSize) {
size_t totalSize;
void *ret;
/* Check for overflow */
if (dim1 > SIZE_MAX / dim2 / elemSize)
return (NULL);
totalSize = dim1 * dim2 * elemSize;
ret = xmlMalloc(totalSize);
if (ret != NULL)
memset(ret, 0, totalSize);
return (ret);
}
/** /**
* xmlRegEpxFromParse: * xmlRegEpxFromParse:
* @ctxt: the parser context used to build it * @ctxt: the parser context used to build it
@ -540,8 +572,8 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
#ifdef DEBUG_COMPACTION #ifdef DEBUG_COMPACTION
printf("Final: %d atoms\n", nbatoms); printf("Final: %d atoms\n", nbatoms);
#endif #endif
transitions = (int *) xmlMalloc((nbstates + 1) * transitions = (int *) xmlRegCalloc2(nbstates + 1, nbatoms + 1,
(nbatoms + 1) * sizeof(int)); sizeof(int));
if (transitions == NULL) { if (transitions == NULL) {
xmlFree(stateRemap); xmlFree(stateRemap);
xmlFree(stringRemap); xmlFree(stringRemap);
@ -551,7 +583,6 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
xmlFree(ret); xmlFree(ret);
return(NULL); return(NULL);
} }
memset(transitions, 0, (nbstates + 1) * (nbatoms + 1) * sizeof(int));
/* /*
* Allocate the transition table. The first entry for each * Allocate the transition table. The first entry for each
@ -577,12 +608,9 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
continue; continue;
atomno = stringRemap[trans->atom->no]; atomno = stringRemap[trans->atom->no];
if ((trans->atom->data != NULL) && (transdata == NULL)) { if ((trans->atom->data != NULL) && (transdata == NULL)) {
transdata = (void **) xmlMalloc(nbstates * nbatoms * transdata = (void **) xmlRegCalloc2(nbstates, nbatoms,
sizeof(void *)); sizeof(void *));
if (transdata != NULL) if (transdata == NULL) {
memset(transdata, 0,
nbstates * nbatoms * sizeof(void *));
else {
xmlRegexpErrMemory(ctxt, "compiling regexp"); xmlRegexpErrMemory(ctxt, "compiling regexp");
break; break;
} }