gawk-diffs
[Top][All Lists]
Advanced

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

[gawk-diffs] [SCM] gawk branch, gawk-4.1-stable, updated. gawk-4.1.0-298


From: Andrew J. Schorr
Subject: [gawk-diffs] [SCM] gawk branch, gawk-4.1-stable, updated. gawk-4.1.0-298-g6e5964a
Date: Sun, 20 Apr 2014 14:38:45 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, gawk-4.1-stable has been updated
       via  6e5964a4f6dd7d2476af106387f40c7ae9ead0c5 (commit)
      from  3cdb8b8cf57d6ccfd215d0170c2b616340719d86 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=6e5964a4f6dd7d2476af106387f40c7ae9ead0c5

commit 6e5964a4f6dd7d2476af106387f40c7ae9ead0c5
Author: Andrew J. Schorr <address@hidden>
Date:   Sun Apr 20 10:36:08 2014 -0400

    Improve socket name parsing to avoid false matches on names starting with 
/inet.

diff --git a/ChangeLog b/ChangeLog
index 2133d73..e586bd0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-04-20         Andrew J. Schorr     <address@hidden>
+
+       * io.c (struct inet_socket_info): Define new structure
+       for use in parsing special socket filenames.
+       (inetfile): Parse all components of the special socket filename
+       into the struct inet_socket_info.  Returns true only if it is a
+       valid socket fliename, unlike the previous version which checked
+       for the '/inet[46]?/' prefix only.
+       (redirect): Patch to use updated inetfile() function.
+       (devopen): Remove logic to parse socket filenames, since this has
+       been moved into the inetfile() function.
+       (two_way_open): Update args to inetfile().
+
 2014-04-18         Arnold D. Robbins     <address@hidden>
 
        * configure.ac: Change adding of -export-dynamic for GCC to be
diff --git a/io.c b/io.c
index 2a5c2e7..a6e786f 100644
--- a/io.c
+++ b/io.c
@@ -279,7 +279,23 @@ static RECVALUE (*matchrec)(IOBUF *iop, struct recmatch 
*recm, SCANSTATE *state)
 static int get_a_record(char **out, IOBUF *iop, int *errcode);
 
 static void free_rp(struct redirect *rp);
-static int inetfile(const char *str, int *length, int *family);
+
+struct inet_socket_info {
+       int family;             /* AF_UNSPEC, AF_INET, or AF_INET6 */
+       int protocol;           /* SOCK_STREAM or SOCK_DGRAM */
+       /*
+        * N.B. If we used 'char *' or 'const char *' pointers to the
+        * substrings, it would trigger compiler warnings about the casts
+        * in either inetfile() or devopen().  So we use offset/len to
+        * avoid that.
+        */
+       struct {
+               int offset;
+               int len;
+       } localport, remotehost, remoteport;
+};
+
+static int inetfile(const char *str, struct inet_socket_info *isn);
 
 static NODE *in_PROCINFO(const char *pidx1, const char *pidx2, NODE 
**full_idx);
 static long get_read_timeout(IOBUF *iop);
@@ -713,7 +729,9 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
        int fd;
        const char *what = NULL;
        bool new_rp = false;
-       int len;        /* used with /inet */
+#ifdef HAVE_SOCKETS
+       struct inet_socket_info isi;
+#endif
        static struct redirect *save_rp = NULL; /* hold onto rp that should
                                                 * be freed for reuse
                                                 */
@@ -772,9 +790,9 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
         * Use /inet4 to force IPv4, /inet6 to force IPv6, and plain
         * /inet will be whatever we get back from the system.
         */
-       if (inetfile(str, & len, NULL)) {
+       if (inetfile(str, & isi)) {
                tflag |= RED_SOCKET;
-               if (strncmp(str + len, "tcp/", 4) == 0)
+               if (isi.protocol == SOCK_STREAM)
                        tflag |= RED_TCP;       /* use shutdown when closing */
        }
 #endif /* HAVE_SOCKETS */
@@ -901,7 +919,7 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
                        direction = "to/from";
                        if (! two_way_open(str, rp)) {
 #ifdef HAVE_SOCKETS
-                               if (inetfile(str, NULL, NULL)) {
+                               if (inetfile(str, NULL)) {
                                        *errflg = errno;
                                        /* do not free rp, saving it for reuse 
(save_rp = rp) */
                                        return NULL;
@@ -1538,8 +1556,7 @@ devopen(const char *name, const char *mode)
        char *cp;
        char *ptr;
        int flag = 0;
-       int len;
-       int family;
+       struct inet_socket_info isi;
 
        if (strcmp(name, "-") == 0)
                return fileno(stdin);
@@ -1576,74 +1593,14 @@ devopen(const char *name, const char *mode)
                /* do not set close-on-exec for inherited fd's */
                if (openfd != INVALID_HANDLE)
                        return openfd;
-       } else if (inetfile(name, & len, & family)) {
+       } else if (inetfile(name, & isi)) {
 #ifdef HAVE_SOCKETS
-               /* /inet/protocol/localport/hostname/remoteport */
-               int protocol;
-               char *hostname;
-               char *hostnameslastcharp;
-               char *localpname;
-               char *localpnamelastcharp;
-
-               cp = (char *) name + len;
-               /* which protocol? */
-               if (strncmp(cp, "tcp/", 4) == 0)
-                       protocol = SOCK_STREAM;
-               else if (strncmp(cp, "udp/", 4) == 0)
-                       protocol = SOCK_DGRAM;
-               else {
-                       protocol = SOCK_STREAM; /* shut up the compiler */
-                       fatal(_("no (known) protocol supplied in special 
filename `%s'"),
-                                               name);
-               }
-               cp += 4;
-
-               /* which localport? */
-               localpname = cp;
-               while (*cp != '/' && *cp != '\0')
-                       cp++;
-               /*                    
-                * Require a port, let them explicitly put 0 if
-                * they don't care.  
-                */
-               if (*cp != '/' || cp == localpname)
-                       fatal(_("special file name `%s' is incomplete"), name);
+               cp = (char *) name;
 
-               /*
-                * We change the special file name temporarily because we
-                * need a 0-terminated string here for conversion with atoi().
-                * By using atoi() the use of decimal numbers is enforced.
-                */
-               *cp = '\0';
-               localpnamelastcharp = cp;
-
-               /* which hostname? */
-               cp++;
-               hostname = cp;
-               while (*cp != '/' && *cp != '\0')
-                       cp++; 
-               if (*cp != '/' || cp == hostname) {
-                       *localpnamelastcharp = '/';
-                       fatal(_("must supply a remote hostname to `/inet'"));
-               }
-               *cp = '\0';
-               hostnameslastcharp = cp;
-
-               /* which remoteport? */
-               cp++;
-               /*
-                * The remote port ends the special file name.
-                * This means there already is a '\0' at the end of the string.
-                * Therefore no need to patch any string ending.
-                *
-                * Here too, require a port, let them explicitly put 0 if
-                * they don't care.
-                */
-               if (*cp == '\0') {
-                       *localpnamelastcharp = '/';
-                       *hostnameslastcharp = '/';
-                       fatal(_("must supply a remote port to `/inet'"));
-               }
+               /* socketopen requires NUL-terminated strings */
+               cp[isi.localport.offset+isi.localport.len] = '\0';
+               cp[isi.remotehost.offset+isi.remotehost.len] = '\0';
+               /* remoteport comes last, so already NUL-terminated */
 
                {
 #define DEFAULT_RETRIES 20
@@ -1680,13 +1637,14 @@ devopen(const char *name, const char *mode)
                retries = def_retries;
 
                do {
-                       openfd = socketopen(family, protocol, localpname, cp, 
hostname);
+                       openfd = socketopen(isi.family, isi.protocol, 
name+isi.localport.offset, name+isi.remoteport.offset, 
name+isi.remotehost.offset);
                        retries--;
                } while (openfd == INVALID_HANDLE && retries > 0 && 
usleep(msleep) == 0);
        }
 
-       *localpnamelastcharp = '/';
-       *hostnameslastcharp = '/';
+       /* restore original name string */
+       cp[isi.localport.offset+isi.localport.len] = '/';
+       cp[isi.remotehost.offset+isi.remotehost.len] = '/';
 #else /* ! HAVE_SOCKETS */
        fatal(_("TCP/IP communications are not supported"));
 #endif /* HAVE_SOCKETS */
@@ -1700,9 +1658,8 @@ strictopen:
                /* On OS/2 and Windows directory access via open() is
                   not permitted.  */
                struct stat buf;
-               int l, f;
 
-               if (!inetfile(name, &l, &f)
+               if (!inetfile(name, NULL)
                    && stat(name, & buf) == 0 && S_ISDIR(buf.st_mode))
                        errno = EISDIR;
        }
@@ -1724,7 +1681,7 @@ two_way_open(const char *str, struct redirect *rp)
 
 #ifdef HAVE_SOCKETS
        /* case 1: socket */
-       if (inetfile(str, NULL, NULL)) {
+       if (inetfile(str, NULL)) {
                int fd, newfd;
 
                fd = devopen(str, "rw");
@@ -3751,34 +3708,87 @@ free_rp(struct redirect *rp)
 /* inetfile --- return true for a /inet special file, set other values */
 
 static int
-inetfile(const char *str, int *length, int *family)
+inetfile(const char *str, struct inet_socket_info *isi)
 {
-       bool ret = false;
-
-       if (strncmp(str, "/inet/", 6) == 0) {
-               ret = true;
-               if (length != NULL)
-                       *length = 6;
-               if (family != NULL)
-                       *family = AF_UNSPEC;
-       } else if (strncmp(str, "/inet4/", 7) == 0) {
-               ret = true;
-               if (length != NULL)
-                       *length = 7;
-               if (family != NULL)
-                       *family = AF_INET;
-       } else if (strncmp(str, "/inet6/", 7) == 0) {
-               ret = true;
-               if (length != NULL)
-                       *length = 7;
-               if (family != NULL)
-                       *family = AF_INET6;
+       const char *cp = str;
+       struct inet_socket_info buf;
+
+       /* syntax: /inet/protocol/localport/hostname/remoteport */
+       if (strncmp(cp, "/inet", 5) != 0)
+               /* quick exit */
+               return false;
+       if (! isi)
+               isi = & buf;
+       cp += 5;
+       switch (*cp) {
+       case '/':
+               isi->family = AF_UNSPEC;
+               break;
+       case '4':
+               if (*++cp != '/')
+                       return false;
+               isi->family = AF_INET;
+               break;
+       case '6':
+               if (*++cp != '/')
+                       return false;
+               isi->family = AF_INET6;
+               break;
+       default:
+               return false;
+       }
+       cp++;   /* skip past '/' */
+
+       /* which protocol? */
+       if (strncmp(cp, "tcp/", 4) == 0)
+               isi->protocol = SOCK_STREAM;
+       else if (strncmp(cp, "udp/", 4) == 0)
+               isi->protocol = SOCK_DGRAM;
+       else
+               return false;
+       cp += 4;
+
+       /* which localport? */
+       isi->localport.offset = cp-str;
+       while (*cp != '/' && *cp != '\0')
+               cp++;
+       /*                    
+        * Require a port, let them explicitly put 0 if
+        * they don't care.  
+        */
+       if (*cp != '/' || ((isi->localport.len = 
(cp-str)-isi->localport.offset) == 0))
+               return false;
+
+       /* which hostname? */
+       cp++;
+       isi->remotehost.offset = cp-str;
+       while (*cp != '/' && *cp != '\0')
+               cp++; 
+       if (*cp != '/' || ((isi->remotehost.len = 
(cp-str)-isi->remotehost.offset) == 0))
+               return false;
+
+       /* which remoteport? */
+       cp++;
+       /*
+        * The remote port ends the special file name.
+        * This means there already is a '\0' at the end of the string.
+        * Therefore no need to patch any string ending.
+        *
+        * Here too, require a port, let them explicitly put 0 if
+        * they don't care.
+        */
+       isi->remoteport.offset = cp-str;
+       while (*cp != '/' && *cp != '\0')
+               cp++; 
+       if (*cp != '\0' || ((isi->remoteport.len = 
(cp-str)-isi->remoteport.offset) == 0))
+               return false;
+
 #ifndef HAVE_GETADDRINFO
+       /* final check for IPv6: */
+       if (isi->family == AF_INET6)
                fatal(_("IPv6 communication is not supported"));
 #endif
-       }
-
-       return ret;
+       return true;
 }
 
 /*

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog |   13 ++++
 io.c      |  216 ++++++++++++++++++++++++++++++++-----------------------------
 2 files changed, 126 insertions(+), 103 deletions(-)


hooks/post-receive
-- 
gawk



reply via email to

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