summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libguile/read.c30
-rw-r--r--test-suite/tests/coding.test10
2 files changed, 31 insertions, 9 deletions
diff --git a/libguile/read.c b/libguile/read.c
index f7edc4f8a..419ad1276 100644
--- a/libguile/read.c
+++ b/libguile/read.c
@@ -2046,11 +2046,20 @@ scm_get_hash_procedure (int c)
}
}
-#define SCM_ENCODING_SEARCH_SIZE (500)
+/* Maximum size of an encoding name. This is a bit more than the
+ longest name listed at
+ <http://www.iana.org/assignments/character-sets> ("ISO-2022-JP-2", 13
+ characters.) */
+#define ENCODING_NAME_MAX_SIZE 20
-/* Search the first few hundred characters of a file for an Emacs-like coding
- declaration. Returns either NULL or a string whose storage has been
- allocated with `scm_gc_malloc ()'. */
+/* Number of bytes at the beginning or end of a file that are scanned
+ for a "coding:" declaration. */
+#define SCM_ENCODING_SEARCH_SIZE (500 + ENCODING_NAME_MAX_SIZE)
+
+
+/* Search the SCM_ENCODING_SEARCH_SIZE bytes of a file for an Emacs-like
+ coding declaration. Returns either NULL or a string whose storage
+ has been allocated with `scm_gc_malloc'. */
char *
scm_i_scan_for_encoding (SCM port)
{
@@ -2109,8 +2118,8 @@ scm_i_scan_for_encoding (SCM port)
if ((pos = strstr(pos, "coding")) == NULL)
return NULL;
- pos += strlen("coding");
- if (pos - header >= SCM_ENCODING_SEARCH_SIZE ||
+ pos += strlen ("coding");
+ if (pos - header >= SCM_ENCODING_SEARCH_SIZE ||
(*pos == ':' || *pos == '='))
{
pos ++;
@@ -2119,10 +2128,17 @@ scm_i_scan_for_encoding (SCM port)
}
/* skip spaces */
- while (pos - header <= SCM_ENCODING_SEARCH_SIZE &&
+ while (pos - header <= SCM_ENCODING_SEARCH_SIZE &&
(*pos == ' ' || *pos == '\t'))
pos ++;
+ if (pos - header >= SCM_ENCODING_SEARCH_SIZE - ENCODING_NAME_MAX_SIZE)
+ /* We found the "coding:" string, but there is probably not enough
+ room to store an encoding name in its entirety, so ignore it.
+ This makes sure we do not end up returning a truncated encoding
+ name. */
+ return NULL;
+
/* grab the next token */
encoding_start = pos;
i = 0;
diff --git a/test-suite/tests/coding.test b/test-suite/tests/coding.test
index a8a415ff4..b57ef7da7 100644
--- a/test-suite/tests/coding.test
+++ b/test-suite/tests/coding.test
@@ -1,6 +1,6 @@
;;;; coding.test --- test suite for coding declarations. -*- mode: scheme -*-
;;;;
-;;;; Copyright (C) 2011, 2013 Free Software Foundation, Inc.
+;;;; Copyright (C) 2011, 2013, 2014 Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
@@ -101,4 +101,10 @@
(pass-if-equal "second line, whitespace, nl"
"ISO-8859-1"
- (scan-coding "\n; coding: iso-8859-1 \n")))
+ (scan-coding "\n; coding: iso-8859-1 \n"))
+
+ (pass-if-equal "http://bugs.gnu.org/16463"
+ ;; On Guile <= 2.0.9, this would return "ISO-8".
+ "ISO-8859-1"
+ (scan-coding (string-append (make-string 485 #\space)
+ "; coding: ISO-8859-1"))))