emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 7e2309c6fc6 02/11: etags: fix #line parsing (\\", long lines)


From: Paul Eggert
Subject: master 7e2309c6fc6 02/11: etags: fix #line parsing (\\", long lines)
Date: Tue, 30 Apr 2024 04:26:36 -0400 (EDT)

branch: master
commit 7e2309c6fc67b8149cc4c75f8d7f5f93e60b86c7
Author: Paul Eggert <eggert@cs.ucla.edu>
Commit: Paul Eggert <eggert@cs.ucla.edu>

    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.
---
 lib-src/etags.c | 22 +++++++++++-----------
 1 file 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)
       /* Check whether this is a #line directive. */
       if (result > 12 && strneq (lbp->buffer, "#line ", 6))
        {
-         intmax_t lno;
-         int start = 0;
+         char *lno_start = lbp->buffer + 6;
+         char *lno_end;
+         intmax_t lno = strtoimax (lno_start, &lno_end, 10);
+         char *quoted_filename
+           = lno_start < lno_end ? skip_spaces (lno_end) : NULL;
 
-         if (sscanf (lbp->buffer, "#line %"SCNdMAX" \"%n", &lno, &start) >= 1
-             && start > 0)     /* double quote character found */
+         if (quoted_filename && *quoted_filename == '"')
            {
-             char *endp = lbp->buffer + start;
+             char *endp = quoted_filename;
+             while (*++endp && *endp != '"')
+               endp += *endp == '\\' && endp[1];
 
-             while ((endp = strchr (endp, '"')) != NULL
-                    && endp[-1] == '\\')
-               endp++;
-             if (endp != NULL)
+             if (*endp)
                /* Ok, this is a real #line directive.  Let's deal with it. */
                {
                  char *taggedabsname;  /* absolute name of original file */
                  char *taggedfname;    /* name of original file as given */
-                 char *name;           /* temp var */
+                 char *name = quoted_filename + 1;
 
                  discard_until_line_directive = false; /* found it */
-                 name = lbp->buffer + start;
                  *endp = '\0';
                  canonicalize_filename (name);
                  taggedabsname = absolute_filename (name, tagfiledir);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]