summaryrefslogtreecommitdiff
path: root/lib-src
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2011-01-30 10:17:36 +0100
committerJim Meyering <meyering@redhat.com>2011-01-30 10:17:36 +0100
commit8aec9916dd8213e2efc77ec32cb57256e1f332be (patch)
tree2de47f2c35a4c92f4882522f5c26d8b987f949f1 /lib-src
parent7920f982949ff41796a9be16e8cce5e797e6caa9 (diff)
make-docfile: don't corrupt heap for an invalid .elc file
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/ChangeLog8
-rw-r--r--lib-src/make-docfile.c12
2 files changed, 17 insertions, 3 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index bc76c253ab3..6428819daa3 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,11 @@
+2011-01-30 Jim Meyering <meyering@redhat.com>
+
+ make-docfile: don't corrupt heap for an invalid .elc file
+ "printf '#@1a' > in.elc; ./make-docfile in.elc" would store 0
+ one byte before just-malloc'd saved_string buffer.
+ * make-docfile.c (scan_lisp_file): Diagnose an invalid dynamic
+ doc string length. Also fix an always-false while-loop test.
+
2011-01-29 Eli Zaretskii <eliz@gnu.org>
* makefile.w32-in (LOCAL_FLAGS): Add -I../lib.
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index 0872f9728a2..8addbda0489 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -873,8 +873,8 @@ scan_lisp_file (const char *filename, const char *mode)
c = getc (infile);
if (c == '@')
{
- int length = 0;
- int i;
+ size_t length = 0;
+ size_t i;
/* Read the length. */
while ((c = getc (infile),
@@ -884,6 +884,12 @@ scan_lisp_file (const char *filename, const char *mode)
length += c - '0';
}
+ if (length <= 1)
+ fatal ("invalid dynamic doc string length", "");
+
+ if (c != ' ')
+ fatal ("space not found after dynamic doc string length", "");
+
/* The next character is a space that is counted in the length
but not part of the doc string.
We already read it, so just ignore it. */
@@ -899,7 +905,7 @@ scan_lisp_file (const char *filename, const char *mode)
but it is redundant in DOC. So get rid of it here. */
saved_string[length - 1] = 0;
/* Skip the line break. */
- while (c == '\n' && c == '\r')
+ while (c == '\n' || c == '\r')
c = getc (infile);
/* Skip the following line. */
while (c != '\n' && c != '\r')