This is apparently a new routine in version 3.6.

I upgraded from version 3.5.9 directly to 3.6.1 and ran into an issue.
Postfix failed to start up without any diagnostic output. It took me a bit
to narrow down the failure, but I discovered that this routine was failing
on valid input.

Use of the library routine strtol() is problematic due to the lack of a
direct failure indication. You cannot check errno for a value unless you
zero it before the invocation.

But, I am thinking that we don't really need to check for an overflow or
underflow error from strtol(), since GOOD_MAJOR() and friends already do
range checking. My solution is to simply remove the errno checks.

One other modification I made concerns the comparisons "start < remainder",
which I changed to "start != remainder". There is no guarantee concerning
the location of the buffer returned via "endptr". Its relation to the
original string is undefined, unless no conversion was done, in which case
it returns the original string.

Patch attached.

David Bohman
diff --git a/src/global/compat_level.c b/src/global/compat_level.c
index 1fb3a68..b0bd93e 100644
--- a/src/global/compat_level.c
+++ b/src/global/compat_level.c
@@ -98,7 +98,6 @@
 #include <sys_defs.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <limits.h>
 
  /*
@@ -158,22 +157,21 @@ long    compat_level_from_string(const char *str,
 
     start = str;
     major = strtol(start, &remainder, 10);
-    if (start < remainder && (*remainder == 0 || *remainder == '.')
-	&& errno != ERANGE && GOOD_MAJOR(major)) {
+    if (start != remainder && (*remainder == 0 || *remainder == '.')
+	&& GOOD_MAJOR(major)) {
 	res = ENCODE_MAJOR(major);
 	if (*remainder == 0)
 	    return res;
 	start = remainder + 1;
 	minor = strtol(start, &remainder, 10);
-	if (start < remainder && (*remainder == 0 || *remainder == '.')
-	    && errno != ERANGE && GOOD_MINOR(minor)) {
+	if (start != remainder && (*remainder == 0 || *remainder == '.')
+	    && GOOD_MINOR(minor)) {
 	    res |= ENCODE_MINOR(minor);
 	    if (*remainder == 0)
 		return (res);
 	    start = remainder + 1;
 	    patch = strtol(start, &remainder, 10);
-	    if (start < remainder && *remainder == 0 && errno != ERANGE
-		&& GOOD_PATCH(patch)) {
+	    if (start != remainder && *remainder == 0 && GOOD_PATCH(patch)) {
 		return (res | ENCODE_PATCH(patch));
 	    }
 	}

Reply via email to