From fbb2b69c8f478c2910a32e25d80eaf67d0dd3cbf Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 2 Sep 2008 20:37:55 +0000
Subject: [PATCH] Prevent memory leaks in our various bison parsers when an
 error occurs during parsing.  Formerly the parser's stack was allocated with
 malloc and so wouldn't be reclaimed; this patch makes it use palloc instead,
 so that flushing the current context will reclaim the memory.  Per Marko
 Kreen.

---
 contrib/cube/cubeparse.y          | 13 ++++++++++++-
 contrib/seg/segparse.y            | 11 +++++++++++
 src/backend/bootstrap/bootparse.y | 13 ++++++++++++-
 src/backend/parser/gram.y         | 13 ++++++++++++-
 src/pl/plpgsql/src/gram.y         | 14 +++++++++++++-
 5 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/contrib/cube/cubeparse.y b/contrib/cube/cubeparse.y
index e867dc8731a..eefe5c47b99 100644
--- a/contrib/cube/cubeparse.y
+++ b/contrib/cube/cubeparse.y
@@ -2,7 +2,7 @@
 /* NdBox = [(lowerleft),(upperright)] */
 /* [(xLL(1)...xLL(N)),(xUR(1)...xUR(n))] */
 
-/* $PostgreSQL: pgsql/contrib/cube/cubeparse.y,v 1.17 2007/02/27 23:48:05 tgl Exp $ */
+/* $PostgreSQL: pgsql/contrib/cube/cubeparse.y,v 1.18 2008/09/02 20:37:54 tgl Exp $ */
 
 #define YYPARSE_PARAM result  /* need this to pass a pointer (void *) to yyparse */
 #define YYSTYPE char *
@@ -12,6 +12,17 @@
 
 #include "cubedata.h"
 
+/*
+ * Bison doesn't allocate anything that needs to live across parser calls,
+ * so we can easily have it use palloc instead of malloc.  This prevents
+ * memory leaks if we error out during parsing.  Note this only works with
+ * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
+ * if possible, so there's not really much problem anyhow, at least if
+ * you're building with gcc.
+ */
+#define YYMALLOC palloc
+#define YYFREE   pfree
+
 extern int cube_yylex(void);
 
 static char *scanbuf;
diff --git a/contrib/seg/segparse.y b/contrib/seg/segparse.y
index dc56fb580fe..47e3d398aae 100644
--- a/contrib/seg/segparse.y
+++ b/contrib/seg/segparse.y
@@ -9,6 +9,17 @@
 #include "utils/builtins.h"
 #include "segdata.h"
 
+/*
+ * Bison doesn't allocate anything that needs to live across parser calls,
+ * so we can easily have it use palloc instead of malloc.  This prevents
+ * memory leaks if we error out during parsing.  Note this only works with
+ * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
+ * if possible, so there's not really much problem anyhow, at least if
+ * you're building with gcc.
+ */
+#define YYMALLOC palloc
+#define YYFREE   pfree
+
   extern int seg_yylex(void);
 
   extern int significant_digits(char *str);		/* defined in seg.c */
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 8019b244ae8..9997566002e 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.93 2008/09/01 20:42:43 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.94 2008/09/02 20:37:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -54,6 +54,17 @@
 #define atooid(x)	((Oid) strtoul((x), NULL, 10))
 
 
+/*
+ * Bison doesn't allocate anything that needs to live across parser calls,
+ * so we can easily have it use palloc instead of malloc.  This prevents
+ * memory leaks if we error out during parsing.  Note this only works with
+ * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
+ * if possible, so there's not really much problem anyhow, at least if
+ * you're building with gcc.
+ */
+#define YYMALLOC palloc
+#define YYFREE   pfree
+
 static void
 do_start(void)
 {
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 26a3198d37b..5c716dd8f22 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.621 2008/09/01 20:42:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.622 2008/09/02 20:37:54 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -79,6 +79,17 @@
  */
 #define base_yylex filtered_base_yylex
 
+/*
+ * Bison doesn't allocate anything that needs to live across parser calls,
+ * so we can easily have it use palloc instead of malloc.  This prevents
+ * memory leaks if we error out during parsing.  Note this only works with
+ * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
+ * if possible, so there's not really much problem anyhow, at least if
+ * you're building with gcc.
+ */
+#define YYMALLOC palloc
+#define YYFREE   pfree
+
 extern List *parsetree;			/* final parse result is delivered here */
 
 static bool QueryIsRule = FALSE;
diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y
index dfd37f67717..cf3c751cc0b 100644
--- a/src/pl/plpgsql/src/gram.y
+++ b/src/pl/plpgsql/src/gram.y
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.113 2008/05/15 22:39:49 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.114 2008/09/02 20:37:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,6 +19,18 @@
 #include "parser/parser.h"
 
 
+/*
+ * Bison doesn't allocate anything that needs to live across parser calls,
+ * so we can easily have it use palloc instead of malloc.  This prevents
+ * memory leaks if we error out during parsing.  Note this only works with
+ * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
+ * if possible, so there's not really much problem anyhow, at least if
+ * you're building with gcc.
+ */
+#define YYMALLOC palloc
+#define YYFREE   pfree
+
+
 static PLpgSQL_expr		*read_sql_construct(int until,
 											int until2,
 											int until3,
-- 
GitLab