From bfda9706489172f3d349b84ef186c37392db7b9a Mon Sep 17 00:00:00 2001
From: Andrei Latchescu <andrei-osre@netrom.ro>
Date: Wed, 23 Jun 2021 11:34:45 +0300
Subject: [PATCH] Fix #78987 - Memory problems running finfo::buffer

---
 ext/fileinfo/libmagic/apprentice.c | 1 +
 ext/fileinfo/libmagic/encoding.c   | 3 +++
 ext/fileinfo/libmagic/file.h       | 2 ++
 ext/fileinfo/libmagic/magic.c      | 9 ++++++++-
 ext/fileinfo/libmagic/magic.h      | 1 +
 5 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/ext/fileinfo/libmagic/apprentice.c b/ext/fileinfo/libmagic/apprentice.c
index 94e4302d619e..1c770a5454be 100644
--- a/ext/fileinfo/libmagic/apprentice.c
+++ b/ext/fileinfo/libmagic/apprentice.c
@@ -511,6 +511,7 @@ file_ms_alloc(int flags)
 	ms->elf_notes_max = FILE_ELF_NOTES_MAX;
 	ms->regex_max = FILE_REGEX_MAX;
 	ms->bytes_max = FILE_BYTES_MAX;
+	ms->encoding_max = FILE_ENCODING_MAX;
 	return ms;
 free:
 	efree(ms);
diff --git a/ext/fileinfo/libmagic/encoding.c b/ext/fileinfo/libmagic/encoding.c
index 42aa200f3652..6af97277fcd1 100644
--- a/ext/fileinfo/libmagic/encoding.c
+++ b/ext/fileinfo/libmagic/encoding.c
@@ -87,6 +87,9 @@ file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
 	*code = "unknown";
 	*code_mime = "binary";
 
+	if (nbytes > ms->encoding_max)
+		nbytes = ms->encoding_max;
+
 	mlen = (nbytes + 1) * sizeof((*ubuf)[0]);
 	if ((*ubuf = CAST(unichar *, ecalloc((size_t)1, mlen))) == NULL) {
 		file_oomem(ms, mlen);
diff --git a/ext/fileinfo/libmagic/file.h b/ext/fileinfo/libmagic/file.h
index 9cb6dc540faf..84e58ce9b5dc 100644
--- a/ext/fileinfo/libmagic/file.h
+++ b/ext/fileinfo/libmagic/file.h
@@ -432,12 +432,14 @@ struct magic_set {
 	uint16_t elf_notes_max;
 	uint16_t regex_max;
 	size_t bytes_max;		/* number of bytes to read from file */
+    size_t encoding_max;		/* bytes to look for encoding */
 #define	FILE_INDIR_MAX			50
 #define	FILE_NAME_MAX			30
 #define	FILE_ELF_SHNUM_MAX		32768
 #define	FILE_ELF_PHNUM_MAX		2048
 #define	FILE_ELF_NOTES_MAX		256
 #define	FILE_REGEX_MAX			8192
+#define	FILE_ENCODING_MAX		(64 * 1024)
 };
 
 /* Type for Unicode characters */
diff --git a/ext/fileinfo/libmagic/magic.c b/ext/fileinfo/libmagic/magic.c
index 51570c2a3751..bc9ae251aa4e 100644
--- a/ext/fileinfo/libmagic/magic.c
+++ b/ext/fileinfo/libmagic/magic.c
@@ -8,7 +8,8 @@
  * 1. Redistributions of source code must retain the above copyright
  *    notice immediately at the beginning of the file, without modification,
  *    this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
+ * 2. Redistributions in binary form must re
+ * produce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
@@ -382,6 +383,9 @@ magic_setparam(struct magic_set *ms, int param, const void *val)
 	case MAGIC_PARAM_BYTES_MAX:
 		ms->bytes_max = *(const size_t *)val;
 		return 0;
+    case MAGIC_PARAM_ENCODING_MAX:
+        ms->encoding_max = *CAST(const size_t *, val);
+        return 0;
 	default:
 		errno = EINVAL;
 		return -1;
@@ -413,6 +417,9 @@ magic_getparam(struct magic_set *ms, int param, void *val)
 	case MAGIC_PARAM_BYTES_MAX:
 		*(size_t *)val = ms->bytes_max;
 		return 0;
+    case MAGIC_PARAM_ENCODING_MAX:
+        *(size_t *)val = ms->encoding_max;
+        return 0;
 	default:
 		errno = EINVAL;
 		return -1;
diff --git a/ext/fileinfo/libmagic/magic.h b/ext/fileinfo/libmagic/magic.h
index a5ba79f0597e..4c1b608ab629 100644
--- a/ext/fileinfo/libmagic/magic.h
+++ b/ext/fileinfo/libmagic/magic.h
@@ -146,6 +146,7 @@ int magic_errno(magic_t);
 #define MAGIC_PARAM_ELF_NOTES_MAX	4
 #define MAGIC_PARAM_REGEX_MAX		5
 #define	MAGIC_PARAM_BYTES_MAX		6
+#define	MAGIC_PARAM_ENCODING_MAX	7
 
 int magic_setparam(magic_t, int, const void *);
 int magic_getparam(magic_t, int, void *);