From 376784cf8ac7dee831471d7fd4159145d135636b Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 8 Dec 2000 23:57:03 +0000
Subject: [PATCH] Repair erroneous use of hashvarlena() for MACADDR, which is
 not a varlena type.  (I did not force initdb, but you won't see the fix
 unless you do one.)  Also, make sure all index support operators and
 functions are careful not to leak memory for toasted inputs; I had missed
 some hash and rtree support ops on this point before.

---
 src/backend/access/hash/hashfunc.c | 10 +++-
 src/backend/access/rtree/rtproc.c  |  5 +-
 src/backend/utils/adt/geo_ops.c    | 94 ++++++++++++++++++++++++------
 src/backend/utils/adt/mac.c        | 15 ++++-
 src/backend/utils/adt/varchar.c    | 10 +++-
 src/include/catalog/pg_amproc.h    |  4 +-
 src/include/catalog/pg_proc.h      |  4 +-
 src/include/utils/builtins.h       |  3 +-
 8 files changed, 115 insertions(+), 30 deletions(-)

diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c
index 362738e6764..d431cbafa23 100644
--- a/src/backend/access/hash/hashfunc.c
+++ b/src/backend/access/hash/hashfunc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.27 2000/06/19 03:54:17 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.28 2000/12/08 23:57:02 tgl Exp $
  *
  * NOTES
  *	  These functions are stored in pg_amproc.	For each operator class
@@ -106,8 +106,14 @@ Datum
 hashvarlena(PG_FUNCTION_ARGS)
 {
 	struct varlena *key = PG_GETARG_VARLENA_P(0);
+	Datum		result;
 
-	return hash_any(VARDATA(key), VARSIZE(key) - VARHDRSZ);
+	result = hash_any(VARDATA(key), VARSIZE(key) - VARHDRSZ);
+
+	/* Avoid leaking memory for toasted inputs */
+	PG_FREE_IF_COPY(key, 0);
+
+	return result;
 }
 
 
diff --git a/src/backend/access/rtree/rtproc.c b/src/backend/access/rtree/rtproc.c
index dfe5805a6b0..6ee95fbc445 100644
--- a/src/backend/access/rtree/rtproc.c
+++ b/src/backend/access/rtree/rtproc.c
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.29 2000/07/30 20:43:40 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.30 2000/12/08 23:57:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -183,5 +183,8 @@ rt_poly_size(PG_FUNCTION_ARGS)
 		*size = (float) (xdim * ydim);
 	}
 
+	/* Avoid leaking memory when handed toasted input. */
+	PG_FREE_IF_COPY(a, 0);
+
 	PG_RETURN_VOID();
 }
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index 3a5591ba5d2..d120442cc5a 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.55 2000/12/03 20:45:35 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.56 2000/12/08 23:57:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3097,8 +3097,15 @@ poly_left(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
 
-	PG_RETURN_BOOL(polya->boundbox.high.x < polyb->boundbox.low.x);
+	result = polya->boundbox.high.x < polyb->boundbox.low.x;
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 /*-------------------------------------------------------
@@ -3111,8 +3118,15 @@ poly_overleft(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
+
+	result = polya->boundbox.low.x <= polyb->boundbox.high.x;
 
-	PG_RETURN_BOOL(polya->boundbox.low.x <= polyb->boundbox.high.x);
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 /*-------------------------------------------------------
@@ -3125,8 +3139,15 @@ poly_right(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
+
+	result = polya->boundbox.low.x > polyb->boundbox.high.x;
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
 
-	PG_RETURN_BOOL(polya->boundbox.low.x > polyb->boundbox.high.x);
+	PG_RETURN_BOOL(result);
 }
 
 /*-------------------------------------------------------
@@ -3139,8 +3160,15 @@ poly_overright(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
 
-	PG_RETURN_BOOL(polya->boundbox.high.x > polyb->boundbox.low.x);
+	result = polya->boundbox.high.x > polyb->boundbox.low.x;
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 /*-------------------------------------------------------
@@ -3155,11 +3183,18 @@ poly_same(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
 
 	if (polya->npts != polyb->npts)
-		PG_RETURN_BOOL(false);
+		result = false;
+	else
+		result = plist_same(polya->npts, polya->p, polyb->p);
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
 
-	PG_RETURN_BOOL(plist_same(polya->npts, polya->p, polyb->p));
+	PG_RETURN_BOOL(result);
 }
 
 /*-----------------------------------------------------------------
@@ -3173,8 +3208,15 @@ poly_overlap(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
+
+	result = box_ov(&polya->boundbox, &polyb->boundbox);
 
-	PG_RETURN_BOOL(box_ov(&polya->boundbox, &polyb->boundbox));
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 
@@ -3186,6 +3228,7 @@ poly_contain(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
 	int			i;
 
 	/*
@@ -3195,6 +3238,7 @@ poly_contain(PG_FUNCTION_ARGS)
 										 BoxPGetDatum(&polya->boundbox),
 										 BoxPGetDatum(&polyb->boundbox))))
 	{
+		result = true;			/* assume true for now */
 		for (i = 0; i < polyb->npts; i++)
 		{
 			if (point_inside(&(polyb->p[i]), polya->npts, &(polya->p[0])) == 0)
@@ -3202,28 +3246,40 @@ poly_contain(PG_FUNCTION_ARGS)
 #if GEODEBUG
 				printf("poly_contain- point (%f,%f) not in polygon\n", polyb->p[i].x, polyb->p[i].y);
 #endif
-				PG_RETURN_BOOL(false);
+				result = false;
+				break;
 			}
 		}
-		for (i = 0; i < polya->npts; i++)
+		if (result)
 		{
-			if (point_inside(&(polya->p[i]), polyb->npts, &(polyb->p[0])) == 1)
+			for (i = 0; i < polya->npts; i++)
 			{
+				if (point_inside(&(polya->p[i]), polyb->npts, &(polyb->p[0])) == 1)
+				{
 #if GEODEBUG
-				printf("poly_contain- point (%f,%f) in polygon\n", polya->p[i].x, polya->p[i].y);
+					printf("poly_contain- point (%f,%f) in polygon\n", polya->p[i].x, polya->p[i].y);
 #endif
-				PG_RETURN_BOOL(false);
+					result = false;
+					break;
+				}
 			}
 		}
-		PG_RETURN_BOOL(true);
 	}
-
+	else
+	{
 #if GEODEBUG
-	printf("poly_contain- bound box ((%f,%f),(%f,%f)) not inside ((%f,%f),(%f,%f))\n",
-		   polyb->boundbox.low.x, polyb->boundbox.low.y, polyb->boundbox.high.x, polyb->boundbox.high.y,
-		   polya->boundbox.low.x, polya->boundbox.low.y, polya->boundbox.high.x, polya->boundbox.high.y);
+		printf("poly_contain- bound box ((%f,%f),(%f,%f)) not inside ((%f,%f),(%f,%f))\n",
+			   polyb->boundbox.low.x, polyb->boundbox.low.y, polyb->boundbox.high.x, polyb->boundbox.high.y,
+			   polya->boundbox.low.x, polya->boundbox.low.y, polya->boundbox.high.x, polya->boundbox.high.y);
 #endif
-	PG_RETURN_BOOL(false);
+		result = false;
+	}
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 
diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c
index 5e949ea2e6e..17754588e97 100644
--- a/src/backend/utils/adt/mac.c
+++ b/src/backend/utils/adt/mac.c
@@ -1,11 +1,12 @@
 /*
  *	PostgreSQL type definitions for MAC addresses.
  *
- *	$Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.18 2000/08/23 06:04:33 thomas Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.19 2000/12/08 23:57:03 tgl Exp $
  */
 
 #include "postgres.h"
 
+#include "access/hash.h"
 #include "utils/builtins.h"
 #include "utils/inet.h"
 
@@ -236,11 +237,21 @@ macaddr_ne(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) != 0);
 }
 
+/*
+ * Support function for hash indexes on macaddr.
+ */
+Datum
+hashmacaddr(PG_FUNCTION_ARGS)
+{
+	macaddr	   *key = PG_GETARG_MACADDR_P(0);
+
+	return hash_any((char *) key, sizeof(macaddr));
+}
+
 /*
  *	Truncation function to allow comparing mac manufacturers.
  *	From suggestion by Alex Pilosov <alex@pilosoft.com>
  */
-
 Datum
 macaddr_trunc(PG_FUNCTION_ARGS)
 {
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 3c58a254619..750d3dd665e 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.71 2000/11/26 11:35:23 ishii Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.72 2000/12/08 23:57:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -663,11 +663,17 @@ hashbpchar(PG_FUNCTION_ARGS)
 	BpChar	   *key = PG_GETARG_BPCHAR_P(0);
 	char	   *keydata;
 	int			keylen;
+	Datum		result;
 
 	keydata = VARDATA(key);
 	keylen = bcTruelen(key);
 
-	return hash_any(keydata, keylen);
+	result = hash_any(keydata, keylen);
+
+	/* Avoid leaking memory for toasted inputs */
+	PG_FREE_IF_COPY(key, 0);
+
+	return result;
 }
 
 
diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h
index dcca94f7f83..02b891cda4c 100644
--- a/src/include/catalog/pg_amproc.h
+++ b/src/include/catalog/pg_amproc.h
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_amproc.h,v 1.25 2000/08/21 04:48:51 tgl Exp $
+ * $Id: pg_amproc.h,v 1.26 2000/12/08 23:57:02 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -114,7 +114,7 @@ DATA(insert OID = 0 (405  431  456 1));
 DATA(insert OID = 0 (405  435  457 1));
 DATA(insert OID = 0 (405  652  456 1));
 DATA(insert OID = 0 (405  754  949 1));
-DATA(insert OID = 0 (405  810  456 1));
+DATA(insert OID = 0 (405  810  399 1));
 DATA(insert OID = 0 (405  935  456 1));
 DATA(insert OID = 0 (405 1076 1080 1));
 DATA(insert OID = 0 (405 1077  456 1));
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 0807ade9efa..fca00930259 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_proc.h,v 1.177 2000/12/07 18:38:58 tgl Exp $
+ * $Id: pg_proc.h,v 1.178 2000/12/08 23:57:02 tgl Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -830,6 +830,8 @@ DATA(insert OID = 456 (  hashvarlena	   PGUID 12 f t t t 1 f 23 "0" 100 0 0 100
 DESCR("hash any varlena type");
 DATA(insert OID = 457 (  hashoidvector	   PGUID 12 f t t t 1 f 23 "30" 100 0 0 100  hashoidvector - ));
 DESCR("hash");
+DATA(insert OID = 399 (  hashmacaddr	   PGUID 12 f t t t 1 f 23 "829" 100 0 0 100  hashmacaddr - ));
+DESCR("hash");
 DATA(insert OID = 458 (  text_larger	   PGUID 12 f t t t 2 f 25 "25 25" 100 0 0 100  text_larger - ));
 DESCR("larger of two");
 DATA(insert OID = 459 (  text_smaller	   PGUID 12 f t t t 2 f 25 "25 25" 100 0 0 100  text_smaller - ));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 7caf379a115..97f03b75a2d 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: builtins.h,v 1.143 2000/11/25 20:33:54 tgl Exp $
+ * $Id: builtins.h,v 1.144 2000/12/08 23:57:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -522,6 +522,7 @@ extern Datum macaddr_ne(PG_FUNCTION_ARGS);
 extern Datum macaddr_trunc(PG_FUNCTION_ARGS);
 extern Datum macaddr_text(PG_FUNCTION_ARGS);
 extern Datum text_macaddr(PG_FUNCTION_ARGS);
+extern Datum hashmacaddr(PG_FUNCTION_ARGS);
 
 /* numeric.c */
 extern Datum numeric_in(PG_FUNCTION_ARGS);
-- 
GitLab