From f1f39911e0d2d88c98eae96a3eb14a53c664206f Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 30 Nov 2019 22:37:25 +0300 Subject: Upgrade to 12.1 --- libpq/pqexpbuffer.c | 430 ---------------------------------------------------- 1 file changed, 430 deletions(-) delete mode 100644 libpq/pqexpbuffer.c (limited to 'libpq/pqexpbuffer.c') diff --git a/libpq/pqexpbuffer.c b/libpq/pqexpbuffer.c deleted file mode 100644 index 8d82d5c..0000000 --- a/libpq/pqexpbuffer.c +++ /dev/null @@ -1,430 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pqexpbuffer.c - * - * PQExpBuffer provides an indefinitely-extensible string data type. - * It can be used to buffer either ordinary C strings (null-terminated text) - * or arbitrary binary data. All storage is allocated with malloc(). - * - * This module is essentially the same as the backend's StringInfo data type, - * but it is intended for use in frontend libpq and client applications. - * Thus, it does not rely on palloc() nor elog(), nor psprintf.c which - * will exit() on error. - * - * It does rely on vsnprintf(); if configure finds that libc doesn't provide - * a usable vsnprintf(), then a copy of our own implementation of it will - * be linked into libpq. - * - * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/interfaces/libpq/pqexpbuffer.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include - -#include "pqexpbuffer.h" - -#ifdef WIN32 -#include "win32.h" -#endif - - -/* All "broken" PQExpBuffers point to this string. */ -static const char oom_buffer[1] = ""; - -static bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) pg_attribute_printf(2, 0); - - -/* - * markPQExpBufferBroken - * - * Put a PQExpBuffer in "broken" state if it isn't already. - */ -static void -markPQExpBufferBroken(PQExpBuffer str) -{ - if (str->data != oom_buffer) - free(str->data); - - /* - * Casting away const here is a bit ugly, but it seems preferable to not - * marking oom_buffer const. We want to do that to encourage the compiler - * to put oom_buffer in read-only storage, so that anyone who tries to - * scribble on a broken PQExpBuffer will get a failure. - */ - str->data = (char *) oom_buffer; - str->len = 0; - str->maxlen = 0; -} - -/* - * createPQExpBuffer - * - * Create an empty 'PQExpBufferData' & return a pointer to it. - */ -PQExpBuffer -createPQExpBuffer(void) -{ - PQExpBuffer res; - - res = (PQExpBuffer) malloc(sizeof(PQExpBufferData)); - if (res != NULL) - initPQExpBuffer(res); - - return res; -} - -/* - * initPQExpBuffer - * - * Initialize a PQExpBufferData struct (with previously undefined contents) - * to describe an empty string. - */ -void -initPQExpBuffer(PQExpBuffer str) -{ - str->data = (char *) malloc(INITIAL_EXPBUFFER_SIZE); - if (str->data == NULL) - { - str->data = (char *) oom_buffer; /* see comment above */ - str->maxlen = 0; - str->len = 0; - } - else - { - str->maxlen = INITIAL_EXPBUFFER_SIZE; - str->len = 0; - str->data[0] = '\0'; - } -} - -/* - * destroyPQExpBuffer(str); - * - * free()s both the data buffer and the PQExpBufferData. - * This is the inverse of createPQExpBuffer(). - */ -void -destroyPQExpBuffer(PQExpBuffer str) -{ - if (str) - { - termPQExpBuffer(str); - free(str); - } -} - -/* - * termPQExpBuffer(str) - * free()s the data buffer but not the PQExpBufferData itself. - * This is the inverse of initPQExpBuffer(). - */ -void -termPQExpBuffer(PQExpBuffer str) -{ - if (str->data != oom_buffer) - free(str->data); - /* just for luck, make the buffer validly empty. */ - str->data = (char *) oom_buffer; /* see comment above */ - str->maxlen = 0; - str->len = 0; -} - -/* - * resetPQExpBuffer - * Reset a PQExpBuffer to empty - * - * Note: if possible, a "broken" PQExpBuffer is returned to normal. - */ -void -resetPQExpBuffer(PQExpBuffer str) -{ - if (str) - { - if (str->data != oom_buffer) - { - str->len = 0; - str->data[0] = '\0'; - } - else - { - /* try to reinitialize to valid state */ - initPQExpBuffer(str); - } - } -} - -/* - * enlargePQExpBuffer - * Make sure there is enough space for 'needed' more bytes in the buffer - * ('needed' does not include the terminating null). - * - * Returns 1 if OK, 0 if failed to enlarge buffer. (In the latter case - * the buffer is left in "broken" state.) - */ -int -enlargePQExpBuffer(PQExpBuffer str, size_t needed) -{ - size_t newlen; - char *newdata; - - if (PQExpBufferBroken(str)) - return 0; /* already failed */ - - /* - * Guard against ridiculous "needed" values, which can occur if we're fed - * bogus data. Without this, we can get an overflow or infinite loop in - * the following. - */ - if (needed >= ((size_t) INT_MAX - str->len)) - { - markPQExpBufferBroken(str); - return 0; - } - - needed += str->len + 1; /* total space required now */ - - /* Because of the above test, we now have needed <= INT_MAX */ - - if (needed <= str->maxlen) - return 1; /* got enough space already */ - - /* - * We don't want to allocate just a little more space with each append; - * for efficiency, double the buffer size each time it overflows. - * Actually, we might need to more than double it if 'needed' is big... - */ - newlen = (str->maxlen > 0) ? (2 * str->maxlen) : 64; - while (needed > newlen) - newlen = 2 * newlen; - - /* - * Clamp to INT_MAX in case we went past it. Note we are assuming here - * that INT_MAX <= UINT_MAX/2, else the above loop could overflow. We - * will still have newlen >= needed. - */ - if (newlen > (size_t) INT_MAX) - newlen = (size_t) INT_MAX; - - newdata = (char *) realloc(str->data, newlen); - if (newdata != NULL) - { - str->data = newdata; - str->maxlen = newlen; - return 1; - } - - markPQExpBufferBroken(str); - return 0; -} - -/* - * printfPQExpBuffer - * Format text data under the control of fmt (an sprintf-like format string) - * and insert it into str. More space is allocated to str if necessary. - * This is a convenience routine that does the same thing as - * resetPQExpBuffer() followed by appendPQExpBuffer(). - */ -void -printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) -{ - va_list args; - bool done; - - resetPQExpBuffer(str); - - if (PQExpBufferBroken(str)) - return; /* already failed */ - - /* Loop in case we have to retry after enlarging the buffer. */ - do - { - va_start(args, fmt); - done = appendPQExpBufferVA(str, fmt, args); - va_end(args); - } while (!done); -} - -/* - * appendPQExpBuffer - * - * Format text data under the control of fmt (an sprintf-like format string) - * and append it to whatever is already in str. More space is allocated - * to str if necessary. This is sort of like a combination of sprintf and - * strcat. - */ -void -appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) -{ - va_list args; - bool done; - - if (PQExpBufferBroken(str)) - return; /* already failed */ - - /* Loop in case we have to retry after enlarging the buffer. */ - do - { - va_start(args, fmt); - done = appendPQExpBufferVA(str, fmt, args); - va_end(args); - } while (!done); -} - -/* - * appendPQExpBufferVA - * Shared guts of printfPQExpBuffer/appendPQExpBuffer. - * Attempt to format data and append it to str. Returns true if done - * (either successful or hard failure), false if need to retry. - */ -static bool -appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) -{ - size_t avail; - size_t needed; - int nprinted; - - /* - * Try to format the given string into the available space; but if there's - * hardly any space, don't bother trying, just enlarge the buffer first. - */ - if (str->maxlen > str->len + 16) - { - /* - * Note: we intentionally leave one byte unused, as a guard against - * old broken versions of vsnprintf. - */ - avail = str->maxlen - str->len - 1; - - errno = 0; - - nprinted = vsnprintf(str->data + str->len, avail, fmt, args); - - /* - * If vsnprintf reports an error other than ENOMEM, fail. - */ - if (nprinted < 0 && errno != 0 && errno != ENOMEM) - { - markPQExpBufferBroken(str); - return true; - } - - /* - * Note: some versions of vsnprintf return the number of chars - * actually stored, not the total space needed as C99 specifies. And - * at least one returns -1 on failure. Be conservative about - * believing whether the print worked. - */ - if (nprinted >= 0 && (size_t) nprinted < avail - 1) - { - /* Success. Note nprinted does not include trailing null. */ - str->len += nprinted; - return true; - } - - if (nprinted >= 0 && (size_t) nprinted > avail) - { - /* - * This appears to be a C99-compliant vsnprintf, so believe its - * estimate of the required space. (If it's wrong, the logic will - * still work, but we may loop multiple times.) Note that the - * space needed should be only nprinted+1 bytes, but we'd better - * allocate one more than that so that the test above will succeed - * next time. - * - * In the corner case where the required space just barely - * overflows, fail. - */ - if (nprinted > INT_MAX - 2) - { - markPQExpBufferBroken(str); - return true; - } - needed = nprinted + 2; - } - else - { - /* - * Buffer overrun, and we don't know how much space is needed. - * Estimate twice the previous buffer size, but not more than - * INT_MAX. - */ - if (avail >= INT_MAX / 2) - needed = INT_MAX; - else - needed = avail * 2; - } - } - else - { - /* - * We have to guess at how much to enlarge, since we're skipping the - * formatting work. - */ - needed = 32; - } - - /* Increase the buffer size and try again. */ - if (!enlargePQExpBuffer(str, needed)) - return true; /* oops, out of memory */ - - return false; -} - -/* - * appendPQExpBufferStr - * Append the given string to a PQExpBuffer, allocating more space - * if necessary. - */ -void -appendPQExpBufferStr(PQExpBuffer str, const char *data) -{ - appendBinaryPQExpBuffer(str, data, strlen(data)); -} - -/* - * appendPQExpBufferChar - * Append a single byte to str. - * Like appendPQExpBuffer(str, "%c", ch) but much faster. - */ -void -appendPQExpBufferChar(PQExpBuffer str, char ch) -{ - /* Make more room if needed */ - if (!enlargePQExpBuffer(str, 1)) - return; - - /* OK, append the character */ - str->data[str->len] = ch; - str->len++; - str->data[str->len] = '\0'; -} - -/* - * appendBinaryPQExpBuffer - * - * Append arbitrary binary data to a PQExpBuffer, allocating more space - * if necessary. - */ -void -appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen) -{ - /* Make more room if needed */ - if (!enlargePQExpBuffer(str, datalen)) - return; - - /* OK, append the data */ - memcpy(str->data + str->len, data, datalen); - str->len += datalen; - - /* - * Keep a trailing null in place, even though it's probably useless for - * binary data... - */ - str->data[str->len] = '\0'; -} -- cgit v1.1