From dc7e8dee9d74058426dcdab44c7023089cf7e10b Mon Sep 17 00:00:00 2001
From: Andrey <amborodin@acm.org>
Date: Mon, 24 Jun 2019 13:38:20 +0500
Subject: [PATCH] Use memcpy in pglz decompression for long matches

---
 src/common/pg_lzcompress.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/src/common/pg_lzcompress.c b/src/common/pg_lzcompress.c
index 988b3987d0..022ae7d434 100644
--- a/src/common/pg_lzcompress.c
+++ b/src/common/pg_lzcompress.c
@@ -731,15 +731,30 @@ pglz_decompress(const char *source, int32 slen, char *dest,
 
 				/*
 				 * Now we copy the bytes specified by the tag from OUTPUT to
-				 * OUTPUT. It is dangerous and platform dependent to use
-				 * memcpy() here, because the copied areas could overlap
-				 * extremely!
+				 * OUTPUT. The copied areas could overlap, to preven possible
+				 * uncertanity, we copy only non-overlapping regions.
 				 */
 				len = Min(len, destend - dp);
-				while (len--)
+				if (len > 8)
 				{
-					*dp = dp[-off];
-					dp++;
+					while (off <= len)
+					{
+						memcpy(dp, dp - off, off);
+						len -= off;
+						dp+=off;
+						off *= 2;
+					}
+					memcpy(dp, dp - off, len);
+					dp+=len;
+				}
+				else
+				{
+					/* use byte-loop for small matches */
+					while (len--)
+					{
+						*dp = dp[-off];
+						dp++;
+					}
 				}
 			}
 			else
-- 
2.20.1

