aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorPaul Eggert2024-04-30 01:20:12 -0700
committerPaul Eggert2024-04-30 01:26:21 -0700
commit7e2309c6fc67b8149cc4c75f8d7f5f93e60b86c7 (patch)
tree313451a2a683aae3be0e04a043be0c3ea9c6dbfb /lib-src
parentde59c02c685189413c7c5a136224d10152dc8a61 (diff)
downloademacs-7e2309c6fc67b8149cc4c75f8d7f5f93e60b86c7.tar.gz
emacs-7e2309c6fc67b8149cc4c75f8d7f5f93e60b86c7.zip
etags: fix #line parsing (\\", long lines)
* lib-src/etags.c (readline): Don’t mishandle lines like ‘#line 1 "a//"’, which has an escaped backslash before ‘"’. Don’t mishandle lines so long that sscanf overflows %n.
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/etags.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c
index c316b3c7649..57ffbce380c 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -7375,26 +7375,26 @@ readline (linebuffer *lbp, FILE *stream)
7375 /* Check whether this is a #line directive. */ 7375 /* Check whether this is a #line directive. */
7376 if (result > 12 && strneq (lbp->buffer, "#line ", 6)) 7376 if (result > 12 && strneq (lbp->buffer, "#line ", 6))
7377 { 7377 {
7378 intmax_t lno; 7378 char *lno_start = lbp->buffer + 6;
7379 int start = 0; 7379 char *lno_end;
7380 intmax_t lno = strtoimax (lno_start, &lno_end, 10);
7381 char *quoted_filename
7382 = lno_start < lno_end ? skip_spaces (lno_end) : NULL;
7380 7383
7381 if (sscanf (lbp->buffer, "#line %"SCNdMAX" \"%n", &lno, &start) >= 1 7384 if (quoted_filename && *quoted_filename == '"')
7382 && start > 0) /* double quote character found */
7383 { 7385 {
7384 char *endp = lbp->buffer + start; 7386 char *endp = quoted_filename;
7387 while (*++endp && *endp != '"')
7388 endp += *endp == '\\' && endp[1];
7385 7389
7386 while ((endp = strchr (endp, '"')) != NULL 7390 if (*endp)
7387 && endp[-1] == '\\')
7388 endp++;
7389 if (endp != NULL)
7390 /* Ok, this is a real #line directive. Let's deal with it. */ 7391 /* Ok, this is a real #line directive. Let's deal with it. */
7391 { 7392 {
7392 char *taggedabsname; /* absolute name of original file */ 7393 char *taggedabsname; /* absolute name of original file */
7393 char *taggedfname; /* name of original file as given */ 7394 char *taggedfname; /* name of original file as given */
7394 char *name; /* temp var */ 7395 char *name = quoted_filename + 1;
7395 7396
7396 discard_until_line_directive = false; /* found it */ 7397 discard_until_line_directive = false; /* found it */
7397 name = lbp->buffer + start;
7398 *endp = '\0'; 7398 *endp = '\0';
7399 canonicalize_filename (name); 7399 canonicalize_filename (name);
7400 taggedabsname = absolute_filename (name, tagfiledir); 7400 taggedabsname = absolute_filename (name, tagfiledir);