* enlargeStringInfo * * Make sure there is enough space for 'needed' more bytes * ('needed' does not include the terminating null). * * External callers usually need not concern themselves with this, since * all stringinfo.c routines do it automatically. However, if a caller * knows that a StringInfo will eventually become X bytes large, it * can save some palloc overhead by enlarging the
| 296 | * current. This is the desired and indeed critical behavior! |
| 297 | */ |
| 298 | void |
| 299 | enlargeStringInfo(StringInfo str, int needed) |
| 300 | { |
| 301 | int newlen; |
| 302 | |
| 303 | /* |
| 304 | * Guard against out-of-range "needed" values. Without this, we can get |
| 305 | * an overflow or infinite loop in the following. |
| 306 | */ |
| 307 | if (needed < 0) /* should not happen */ |
| 308 | { |
| 309 | #ifndef FRONTEND |
| 310 | elog(ERROR, "invalid string enlargement request size: %d", needed); |
| 311 | #else |
| 312 | fprintf(stderr, "invalid string enlargement request size: %d\n", needed); |
| 313 | exit(EXIT_FAILURE); |
| 314 | #endif |
| 315 | } |
| 316 | if (((Size) needed) >= (MaxAllocSize - (Size) str->len)) |
| 317 | { |
| 318 | #ifndef FRONTEND |
| 319 | ereport(ERROR, |
| 320 | (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), |
| 321 | errmsg("out of memory"), |
| 322 | errdetail("Cannot enlarge string buffer containing %d bytes by %d more bytes.", |
| 323 | str->len, needed))); |
| 324 | #else |
| 325 | fprintf(stderr, |
| 326 | _("out of memory\n\nCannot enlarge string buffer containing %d bytes by %d more bytes.\n"), |
| 327 | str->len, needed); |
| 328 | exit(EXIT_FAILURE); |
| 329 | #endif |
| 330 | } |
| 331 | |
| 332 | needed += str->len + 1; /* total space required now */ |
| 333 | |
| 334 | /* Because of the above test, we now have needed <= MaxAllocSize */ |
| 335 | |
| 336 | if (needed <= str->maxlen) |
| 337 | return; /* got enough space already */ |
| 338 | |
| 339 | /* |
| 340 | * We don't want to allocate just a little more space with each append; |
| 341 | * for efficiency, double the buffer size each time it overflows. |
| 342 | * Actually, we might need to more than double it if 'needed' is big... |
| 343 | */ |
| 344 | newlen = 2 * str->maxlen; |
| 345 | while (needed > newlen) |
| 346 | newlen = 2 * newlen; |
| 347 | |
| 348 | /* |
| 349 | * Clamp to MaxAllocSize in case we went past it. Note we are assuming |
| 350 | * here that MaxAllocSize <= INT_MAX/2, else the above loop could |
| 351 | * overflow. We will still have newlen >= needed. |
| 352 | */ |
| 353 | if (newlen > (int) MaxAllocSize) |
| 354 | newlen = (int) MaxAllocSize; |
| 355 |
no test coverage detected