The branch main has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=550dacea138e5df66780a152ab1ba91c466d7395

commit 550dacea138e5df66780a152ab1ba91c466d7395
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2026-06-29 15:54:00 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
CommitDate: 2026-06-29 15:54:00 +0000

    Revert "libc/resolv: Refactor the option parser"
    
    This reverts commit 40e10af6c6dc46d9c0835db3dc95368ce7d69b55.
---
 lib/libc/resolv/res_init.c | 165 +++++++++++++++++++++------------------------
 1 file changed, 77 insertions(+), 88 deletions(-)

diff --git a/lib/libc/resolv/res_init.c b/lib/libc/resolv/res_init.c
index 20f6824857b5..e9e982fe27bb 100644
--- a/lib/libc/resolv/res_init.c
+++ b/lib/libc/resolv/res_init.c
@@ -3,7 +3,6 @@
  *
  * Copyright (c) 1985, 1989, 1993
  *    The Regents of the University of California.  All rights reserved.
- * Copyright (c) 2026 Dag-Erling Smørgrav
  * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -81,7 +80,6 @@
 #include <arpa/nameser.h>
 
 #include <ctype.h>
-#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -105,11 +103,9 @@ static const char sort_mask[] = "/&";
 static u_int32_t net_mask(struct in_addr);
 #endif
 
-#define res_space(ch)                                                  \
-       isspace((unsigned char)(ch))
-#define res_match(str, end, word)                                      \
-       (strncmp((str), (word), (end) - (str)) == 0 &&                  \
-           (word)[(end) - (str)] == '\0')
+#if !defined(isascii)  /*%< XXX - could be a function */
+# define isascii(c) (!(c & 0200))
+#endif
 
 /*
  * Resolver state default settings.
@@ -524,136 +520,129 @@ __res_vinit(res_state statp, int preinit) {
 static void
 res_setoptions(res_state statp, const char *options, const char *source)
 {
-       const char *cp = options, *sp, *ep;
-       char *numend;
-       long num;
+       const char *cp = options;
+       int i;
        struct __res_state_ext *ext = statp->_u._ext.ext;
 
 #ifdef DEBUG
-       if (statp->options & RES_DEBUG) {
+       if (statp->options & RES_DEBUG)
                printf(";; res_setoptions(\"%s\", \"%s\")...\n",
                       options, source);
-       }
 #endif
-       for (;;) {
+       while (*cp) {
                /* skip leading and inner runs of spaces */
-               while (res_space(*cp))
+               while (*cp == ' ' || *cp == '\t')
                        cp++;
-               /* find the separator if there is one */
-               sp = cp;
-               while (*sp != '\0' && !res_space(*sp) && *sp != ':')
-                       sp++;
-               /* find the end of the option */
-               ep = sp;
-               while (*ep != '\0' && !res_space(*ep))
-                       ep++;
-               /* end of option line */
-               if (ep == cp)
-                       break;
                /* search for and process individual options */
-               if (res_match(cp, sp, "ndots") && sp < ep) {
-                       num = strtol(sp + 1, &numend, 10);
-                       if (numend == ep && num <= RES_MAXNDOTS)
-                               statp->ndots = num;
+               if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
+                       i = atoi(cp + sizeof("ndots:") - 1);
+                       if (i <= RES_MAXNDOTS)
+                               statp->ndots = i;
                        else
                                statp->ndots = RES_MAXNDOTS;
 #ifdef DEBUG
                        if (statp->options & RES_DEBUG)
                                printf(";;\tndots=%d\n", statp->ndots);
 #endif
-               } else if (res_match(cp, sp, "timeout") && sp < ep) {
-                       num = strtol(sp + 1, &numend, 10);
-                       if (numend == ep && num > 0 && num <= RES_MAXRETRANS)
-                               statp->retrans = num;
+               } else if (!strncmp(cp, "timeout:", sizeof("timeout:") - 1)) {
+                       i = atoi(cp + sizeof("timeout:") - 1);
+                       if (i <= RES_MAXRETRANS)
+                               statp->retrans = i;
                        else
                                statp->retrans = RES_MAXRETRANS;
 #ifdef DEBUG
                        if (statp->options & RES_DEBUG)
                                printf(";;\ttimeout=%d\n", statp->retrans);
 #endif
-               } else if (res_match(cp, sp, "attempts") && sp < ep) {
-                       num = strtol(sp + 1, &numend, 10);
-                       if (numend == ep && num > 0 && num <= RES_MAXRETRY)
-                               statp->retry = num;
+               } else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){
+                       i = atoi(cp + sizeof("attempts:") - 1);
+                       if (i <= RES_MAXRETRY)
+                               statp->retry = i;
                        else
                                statp->retry = RES_MAXRETRY;
 #ifdef DEBUG
                        if (statp->options & RES_DEBUG)
                                printf(";;\tattempts=%d\n", statp->retry);
 #endif
-               } else if (res_match(cp, ep, "debug")) {
+               } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
 #ifdef DEBUG
                        if (!(statp->options & RES_DEBUG)) {
                                printf(";; res_setoptions(\"%s\", \"%s\")..\n",
                                       options, source);
+                               statp->options |= RES_DEBUG;
                        }
-#endif
-                       statp->options |= RES_DEBUG;
-#ifdef DEBUG
                        printf(";;\tdebug\n");
 #endif
-               } else if (res_match(cp, ep, "no-tld-query") ||
-                   res_match(cp, ep, "no_tld_query")) {
+               } else if (!strncmp(cp, "no_tld_query",
+                                   sizeof("no_tld_query") - 1) ||
+                          !strncmp(cp, "no-tld-query",
+                                   sizeof("no-tld-query") - 1)) {
                        statp->options |= RES_NOTLDQUERY;
-               } else if (res_match(cp, ep, "inet6")) {
+               } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
                        statp->options |= RES_USE_INET6;
-               } else if (res_match(cp, ep, "insecure1")) {
-                       statp->options |= RES_INSECURE1;
-               } else if (res_match(cp, ep, "insecure2")) {
-                       statp->options |= RES_INSECURE2;
-               } else if (res_match(cp, ep, "blast")) {
-                       statp->options |= RES_BLAST;
-               } else if (res_match(cp, ep, "rotate")) {
+               } else if (!strncmp(cp, "insecure1", sizeof("insecure1") - 1)) {
+                      statp->options |= RES_INSECURE1;
+               } else if (!strncmp(cp, "insecure2", sizeof("insecure2") - 1)) {
+                      statp->options |= RES_INSECURE2;
+               } else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) {
                        statp->options |= RES_ROTATE;
-               } else if (res_match(cp, ep, "usevc")) {
+               } else if (!strncmp(cp, "usevc", sizeof("usevc") - 1)) {
                        statp->options |= RES_USEVC;
-               } else if (res_match(cp, ep, "no-check-names")) {
+               } else if (!strncmp(cp, "no-check-names",
+                                   sizeof("no-check-names") - 1)) {
                        statp->options |= RES_NOCHECKNAME;
-               } else if (res_match(cp, sp, "reload-period") && sp < ep) {
-                       num = strtol(sp + 1, &numend, 10);
-                       if (numend == ep && num > 0 && num <= USHRT_MAX &&
-                           ext != NULL) {
-                               ext->reload_period = (u_short)num;
+               } else if (!strncmp(cp, "reload-period:",
+                                   sizeof("reload-period:") - 1)) {
+                       if (ext != NULL) {
+                               ext->reload_period = (u_short)
+                                   atoi(cp + sizeof("reload-period:") - 1);
                        }
+               }
 #ifdef RES_USE_EDNS0
-               } else if (res_match(cp, ep, "edns0")) {
+               else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
                        statp->options |= RES_USE_EDNS0;
+               }
 #endif
 #ifndef _LIBC
-               } else if (res_match(cp, ep, "dname")) {
+               else if (!strncmp(cp, "dname", sizeof("dname") - 1)) {
                        statp->options |= RES_USE_DNAME;
-               } else if (res_match(cp, sp, "nibble") && sp < ep) {
-                       sp++;
-                       if (ext != NULL && ep - sp < sizeof(ext->nsuffix)) {
-                               strncpy(ext->nsuffix, sp, ep - sp);
-                               ext->nsuffix[ep - sp] = '\0';
-                       }
-               } else if (res_match(cp, sp, "nibble2") && sp < ep) {
-                       sp++;
-                       if (ext != NULL && ep - sp < sizeof(ext->nsuffix2)) {
-                               strncpy(ext->nsuffix2, sp, ep - sp);
-                               ext->nsuffix2[ep - sp] = '\0';
-                       }
-               } else if (res_match(cp, sp, "v6revmode") && sp < ep) {
+               }
+               else if (!strncmp(cp, "nibble:", sizeof("nibble:") - 1)) {
+                       if (ext == NULL)
+                               goto skip;
+                       cp += sizeof("nibble:") - 1;
+                       i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1);
+                       strncpy(ext->nsuffix, cp, i);
+                       ext->nsuffix[i] = '\0';
+               }
+               else if (!strncmp(cp, "nibble2:", sizeof("nibble2:") - 1)) {
+                       if (ext == NULL)
+                               goto skip;
+                       cp += sizeof("nibble2:") - 1;
+                       i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix2) - 1);
+                       strncpy(ext->nsuffix2, cp, i);
+                       ext->nsuffix2[i] = '\0';
+               }
+               else if (!strncmp(cp, "v6revmode:", sizeof("v6revmode:") - 1)) {
+                       cp += sizeof("v6revmode:") - 1;
                        /* "nibble" and "bitstring" used to be valid */
-                       if (res_match(sp + 1, ep, "single"))
+                       if (!strncmp(cp, "single", sizeof("single") - 1)) {
                                statp->options |= RES_NO_NIBBLE2;
-                       else if (res_match(sp + 1, ep, "both"))
-                               statp->options &= ~RES_NO_NIBBLE2;
-#ifdef DEBUG
-                       else
-                               printf(";;\t%.*s: unrecognized value: %.*s\n",
-                                   (int)(sp - cp), cp,
-                                   (int)(ep - sp - 1), sp + 1);
-#endif
-#endif /* !_LIBC */
-               } else {
-#ifdef DEBUG
-                       printf(";;\tunrecognized option: %.*s\n",
-                           (int)(ep - cp), cp);
+                       } else if (!strncmp(cp, "both", sizeof("both") - 1)) {
+                               statp->options &=
+                                        ~RES_NO_NIBBLE2;
+                       }
+               }
 #endif
+               else {
+                       /* XXX - print a warning here? */
                }
-               cp = ep;
+#ifndef _LIBC
+   skip:
+#endif
+               /* skip to next run of spaces */
+               while (*cp && *cp != ' ' && *cp != '\t')
+                       cp++;
        }
 }
 

Reply via email to