Replace static buffers with malloc
authorChristoph Berg <myon@debian.org>
Thu, 6 Jun 2024 13:25:38 +0000 (15:25 +0200)
committerChristoph Berg <myon@debian.org>
Thu, 6 Jun 2024 13:25:38 +0000 (15:25 +0200)
Since we learned to decode TOASTed values these buffers were too small.

Makefile
decode.c
stringinfo.c

index 531ab2305fc6bba3084bb149cf53339403f0ecad..a39bfcae64c383035552781cec219ea3307a6681 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ FD_VERSION=16.0
 
 PROGRAM = pg_filedump
 OBJS = pg_filedump.o decode.o stringinfo.o
-REGRESS = datatypes float numeric xml
+REGRESS = datatypes float numeric xml toast
 TAP_TESTS = 1
 EXTRA_CLEAN = *.heap
 
index 36cee19721d22548686a592467a1dd75e2f08b7a..12200802338cd5d1e6c8a48365733bdc429d1933 100644 (file)
--- a/decode.c
+++ b/decode.c
@@ -237,15 +237,6 @@ static ParseCallbackTableItem callback_table[] =
 static StringInfoData copyString;
 static bool copyStringInitDone = false;
 
-/*
- * Temporary buffer for storing decompressed data.
- *
- * 64K should be enough in most cases. If it's not user can manually change
- * this limit. Unfortunately there is no way to know how much memory user
- * is willing to allocate.
- */
-static char decompress_tmp_buff[64 * 1024];
-
 /* Used by some PostgreSQL macro definitions */
 #if PG_VERSION_NUM < 160000
 void
@@ -302,32 +293,18 @@ CopyAppend(const char *str)
 static int
 CopyAppendEncode(const char *str, int orig_len)
 {
-       /*
-        * Should be enough in most cases. If it's not user can manually change
-        * this limit. Unfortunately there is no way to know how much memory user
-        * is willing to allocate.
-        */
-       static char tmp_buff[64 * 1024];
-
-       /* Reserve one byte for a trailing zero. */
-       const int       max_offset = sizeof(tmp_buff) - 2;
        int                     curr_offset = 0;
        int                     len = orig_len;
+       char       *tmp_buff = malloc(2 * orig_len + 1);
 
-       while (len > 0)
+       if (tmp_buff == NULL)
        {
-               /*
-                * Make sure there is enough free space for at least one special
-                * symbol and a trailing zero.
-                */
-               if (curr_offset > max_offset - 2)
-               {
-                       printf("ERROR: Unable to properly encode a string since it's too "
-                                  "large (%d bytes). Try to increase tmp_buff size in CopyAppendEncode "
-                                  "procedure.\n", orig_len);
-                       exit(1);
-               }
+               perror("malloc");
+               exit(1);
+       }
 
+       while (len > 0)
+       {
                /*
                 * Since we are working with potentially corrupted data we can
                 * encounter \0 as well.
@@ -375,6 +352,8 @@ CopyAppendEncode(const char *str, int orig_len)
 
        tmp_buff[curr_offset] = '\0';
        CopyAppend(tmp_buff);
+       free(tmp_buff);
+
        return 0;
 }
 
@@ -1171,6 +1150,7 @@ extract_data(const char *buffer, unsigned int buff_size, unsigned int *out_size,
                int                                             decompress_ret;
                uint32                                  len = VARSIZE_4B(buffer);
                uint32                                  decompressed_len = 0;
+               char                               *decompress_tmp_buff;
 #if PG_VERSION_NUM >= 140000
                ToastCompressionId              cmid;
 #endif
@@ -1181,19 +1161,13 @@ extract_data(const char *buffer, unsigned int buff_size, unsigned int *out_size,
                decompressed_len = VARRAWSIZE_4B_C(buffer);
 #endif
 
-
                if (len > buff_size)
                        return -1;
 
-               if (decompressed_len > sizeof(decompress_tmp_buff))
+               if ((decompress_tmp_buff = malloc(decompressed_len)) == NULL)
                {
-                       printf("WARNING: Unable to decompress a string since it's too "
-                                  "large (%d bytes after decompressing). Consider increasing "
-                                  "decompress_tmp_buff size.\n", decompressed_len);
-
-                       CopyAppend("(COMPRESSED)");
-                       *out_size = padding + len;
-                       return 0;
+                       perror("malloc");
+                       exit(1);
                }
 
 #if PG_VERSION_NUM >= 140000
@@ -1228,11 +1202,13 @@ extract_data(const char *buffer, unsigned int buff_size, unsigned int *out_size,
                        printf("WARNING: Unable to decompress a string. Data is corrupted.\n");
                        CopyAppend("(COMPRESSED)");
                        *out_size = padding + len;
+                       free(decompress_tmp_buff);
                        return 0;
                }
 
                result = parse_value(decompress_tmp_buff, decompressed_len);
                *out_size = padding + len;
+               free(decompress_tmp_buff);
                return result;
        }
 
index 637d6430fb5d6ce75d56704760fca0941ff6e8c0..4cf22acf4d5f14a0a9e7a69684de771f64ce634f 100644 (file)
@@ -8,8 +8,7 @@
 #include <string.h>
 #include <assert.h>
 
-/* 64 Kb - until pg_filedump doesn't support TOAST it doesn't need more */
-#define MaxAllocSize   ((Size) (64*1024))
+#define MaxAllocSize   ((Size) 0x3fffffff) /* 1 gigabyte - 1 */
 
 /*-------------------------
  * StringInfoData holds information about an extensible string.