| 938 | void * |
| 939 | # else |
| 940 | static void * |
| 941 | # endif |
| 942 | expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine) { |
| 943 | assert(parser != NULL); |
| 944 | |
| 945 | if (ptr == NULL) { |
| 946 | return expat_malloc(parser, size, sourceLine); |
| 947 | } |
| 948 | |
| 949 | if (size == 0) { |
| 950 | expat_free(parser, ptr, sourceLine); |
| 951 | return NULL; |
| 952 | } |
| 953 | |
| 954 | const XML_Parser rootParser = getRootParserOf(parser, NULL); |
| 955 | assert(rootParser->m_parentParser == NULL); |
| 956 | |
| 957 | // Extract original size (to the eyes of the caller) and the original |
| 958 | // pointer returned by malloc/realloc |
| 959 | void *mallocedPtr = (char *)ptr - EXPAT_MALLOC_PADDING - sizeof(size_t); |
| 960 | const size_t prevSize = *(size_t *)mallocedPtr; |
| 961 | |
| 962 | // Classify upcoming change |
| 963 | const bool isIncrease = (size > prevSize); |
| 964 | const size_t absDiff |
| 965 | = (size > prevSize) ? (size - prevSize) : (prevSize - size); |
| 966 | |
| 967 | // Ask for permission from accounting |
| 968 | if (isIncrease) { |
| 969 | if (! expat_heap_increase_tolerable(rootParser, absDiff, sourceLine)) { |
| 970 | return NULL; // i.e. signal violation as out-of-memory |
| 971 | } |
| 972 | } |
| 973 | |
| 974 | // NOTE: Integer overflow detection has already been done for us |
| 975 | // by expat_heap_increase_tolerable(..) above |
| 976 | assert(SIZE_MAX - sizeof(size_t) - EXPAT_MALLOC_PADDING >= size); |
| 977 | |
| 978 | // Actually allocate |
| 979 | mallocedPtr = parser->m_mem.realloc_fcn( |
| 980 | mallocedPtr, sizeof(size_t) + EXPAT_MALLOC_PADDING + size); |
| 981 | |
| 982 | if (mallocedPtr == NULL) { |
| 983 | return NULL; |
| 984 | } |
| 985 | |
| 986 | // Update accounting |
| 987 | if (isIncrease) { |
| 988 | assert((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated |
| 989 | >= absDiff); |
| 990 | rootParser->m_alloc_tracker.bytesAllocated += absDiff; |
| 991 | } else { // i.e. decrease |
| 992 | assert(rootParser->m_alloc_tracker.bytesAllocated >= absDiff); |
| 993 | rootParser->m_alloc_tracker.bytesAllocated -= absDiff; |
| 994 | } |
| 995 | |
| 996 | // Report as needed |
| 997 | if (rootParser->m_alloc_tracker.debugLevel >= 2) { |
nothing calls this directly
no test coverage detected
searching dependent graphs…