Backport of:

From 51fb4c8400fbc1c9273174b5e2e7c76ee03ea292 Mon Sep 17 00:00:00 2001
From: Michael R Sweet <msweet@msweet.org>
Date: Mon, 13 Apr 2026 13:20:38 -0400
Subject: [PATCH] Update processing of LimitRequestBody, MaxLogSize, and
 MaxRequestSize to support full range of file sizes (Issue #1540)

---
 CHANGES.md       |  2 ++
 scheduler/conf.c | 77 ++++++++++++++++++++++++++++++++----------------
 scheduler/conf.h |  8 ++---
 3 files changed, 58 insertions(+), 29 deletions(-)

#diff --git a/CHANGES.md b/CHANGES.md
#index e25202ee86..9b01a096d7 100644
#--- a/CHANGES.md
#+++ b/CHANGES.md
#@@ -39,6 +39,8 @@ Changes in CUPS v2.4.17 (YYYY-MM-DD)
# - Fixed a bug in cgiCheckVariables.
# - Fixed a debug printf bug on Windows (Issue #1529)
# - Fixed a recursion issue with encoding of nested collections (Issue #1539)
#+- Fixed parsing of the `LimitRequestBody`, `MaxLogSize`, and `MaxRequestSize`
#+  directives in "cupsd.conf" (Issue #1540)
# 
# 
# Changes in CUPS v2.4.16 (2025-12-04)
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -46,6 +46,7 @@
 typedef enum
 {
   CUPSD_VARTYPE_INTEGER,		/* Integer option */
+  CUPSD_VARTYPE_SIZE,			/* Size option */
   CUPSD_VARTYPE_TIME,			/* Time interval option */
   CUPSD_VARTYPE_NULLSTRING,		/* String option or NULL/empty string */
   CUPSD_VARTYPE_STRING,			/* String option */
@@ -101,7 +102,7 @@ static const cupsd_var_t	cupsd_vars[] =
 #ifdef HAVE_LAUNCHD
   { "LaunchdTimeout",		&IdleExitTimeout,	CUPSD_VARTYPE_TIME },
 #endif /* HAVE_LAUNCHD */
-  { "LimitRequestBody",		&MaxRequestSize,	CUPSD_VARTYPE_INTEGER },
+  { "LimitRequestBody",		&MaxRequestSize,	CUPSD_VARTYPE_SIZE },
   { "LogDebugHistory",		&LogDebugHistory,	CUPSD_VARTYPE_INTEGER },
   { "MaxActiveJobs",		&MaxActiveJobs,		CUPSD_VARTYPE_INTEGER },
   { "MaxClients",		&MaxClients,		CUPSD_VARTYPE_INTEGER },
@@ -114,8 +115,8 @@ static const cupsd_var_t	cupsd_vars[] =
   { "MaxJobsPerUser",		&MaxJobsPerUser,	CUPSD_VARTYPE_INTEGER },
   { "MaxJobTime",		&MaxJobTime,		CUPSD_VARTYPE_TIME },
   { "MaxLeaseDuration",		&MaxLeaseDuration,	CUPSD_VARTYPE_TIME },
-  { "MaxLogSize",		&MaxLogSize,		CUPSD_VARTYPE_INTEGER },
-  { "MaxRequestSize",		&MaxRequestSize,	CUPSD_VARTYPE_INTEGER },
+  { "MaxLogSize",		&MaxLogSize,		CUPSD_VARTYPE_SIZE },
+  { "MaxRequestSize",		&MaxRequestSize,	CUPSD_VARTYPE_SIZE },
   { "MaxSubscriptions",		&MaxSubscriptions,	CUPSD_VARTYPE_INTEGER },
   { "MaxSubscriptionsPerJob",	&MaxSubscriptionsPerJob,	CUPSD_VARTYPE_INTEGER },
   { "MaxSubscriptionsPerPrinter",&MaxSubscriptionsPerPrinter,	CUPSD_VARTYPE_INTEGER },
@@ -2704,54 +2705,80 @@ parse_variable(
     case CUPSD_VARTYPE_INTEGER :
 	if (!value)
 	{
-	  cupsdLogMessage(CUPSD_LOG_ERROR,
-			  "Missing integer value for %s on line %d of %s.",
-			  line, linenum, filename);
+	  cupsdLogMessage(CUPSD_LOG_ERROR, "Missing integer value for %s on line %d of %s.", line, linenum, filename);
           return (0);
 	}
 	else if (!isdigit(*value & 255))
 	{
-	  cupsdLogMessage(CUPSD_LOG_ERROR,
-			  "Bad integer value for %s on line %d of %s.",
-			  line, linenum, filename);
+	  cupsdLogMessage(CUPSD_LOG_ERROR, "Bad integer value for %s on line %d of %s.", line, linenum, filename);
           return (0);
 	}
 	else
 	{
-	  int	n;		/* Number */
-	  char	*units;		/* Units */
+	  long	n;		/* Number */
+	  char	*ptr;		/* Remaining text */
 
-	  n = strtol(value, &units, 0);
+	  n = strtol(value, &ptr, 0);
+
+	  if (n < 0 || n > INT_MAX || (ptr && *ptr))
+	  {
+	    cupsdLogMessage(CUPSD_LOG_ERROR, "Bad integer value for %s on line %d of %s.", line, linenum, filename);
+	    return (0);
+	  }
+	  else
+	  {
+	    *((int *)var->ptr) = (int)n;
+	  }
+	}
+	break;
+
+    case CUPSD_VARTYPE_SIZE :
+	if (!value)
+	{
+	  cupsdLogMessage(CUPSD_LOG_ERROR, "Missing size value for %s on line %d of %s.", line, linenum, filename);
+          return (0);
+	}
+	else if (!isdigit(*value & 255))
+	{
+	  cupsdLogMessage(CUPSD_LOG_ERROR, "Bad size value for %s on line %d of %s.", line, linenum, filename);
+          return (0);
+	}
+	else
+	{
+	  double	n;		/* Number */
+	  char		*units;		/* Units */
+
+	  n = _cupsStrScand(value, &units, localeconv());
 
 	  if (units && *units)
 	  {
 	    if (tolower(units[0] & 255) == 'g')
-	      n *= 1024 * 1024 * 1024;
+	    {
+	      n *= 1024.0 * 1024.0 * 1024.0;
+	    }
 	    else if (tolower(units[0] & 255) == 'm')
-	      n *= 1024 * 1024;
+	    {
+	      n *= 1024.0 * 1024.0;
+	    }
 	    else if (tolower(units[0] & 255) == 'k')
-	      n *= 1024;
-	    else if (tolower(units[0] & 255) == 't')
-	      n *= 262144;
+	    {
+	      n *= 1024.0;
+	    }
 	    else
 	    {
-	      cupsdLogMessage(CUPSD_LOG_ERROR,
-			      "Unknown integer value for %s on line %d of %s.",
-			      line, linenum, filename);
+	      cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown size units for %s on line %d of %s.", line, linenum, filename);
 	      return (0);
 	    }
 	  }
 
-	  if (n < 0)
+	  if (n < 0 || n > (double)OFF_MAX)
 	  {
-	    cupsdLogMessage(CUPSD_LOG_ERROR,
-			    "Bad negative integer value for %s on line %d of "
-			    "%s.", line, linenum, filename);
+	    cupsdLogMessage(CUPSD_LOG_ERROR, "Bad size value for %s on line %d of %s.", line, linenum, filename);
 	    return (0);
 	  }
 	  else
 	  {
-	    *((int *)var->ptr) = n;
+	    *((off_t *)var->ptr) = (off_t)n;
 	  }
 	}
 	break;
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -188,13 +188,13 @@ VAR int			MaxClients		VALUE(100),
 					/* Maximum number of clients */
 			MaxClientsPerHost	VALUE(0),
 					/* Maximum number of clients per host */
-			MaxCopies		VALUE(CUPS_DEFAULT_MAX_COPIES),
+			MaxCopies		VALUE(CUPS_DEFAULT_MAX_COPIES);
 					/* Maximum number of copies per job */
-			MaxLogSize		VALUE(1024 * 1024),
+VAR off_t		MaxLogSize		VALUE(1024 * 1024),
 					/* Maximum size of log files */
-			MaxRequestSize		VALUE(0),
+			MaxRequestSize		VALUE(0);
 					/* Maximum size of IPP requests */
-			HostNameLookups		VALUE(FALSE),
+VAR int			HostNameLookups		VALUE(FALSE),
 					/* Do we do reverse lookups? */
 			Timeout			VALUE(DEFAULT_TIMEOUT),
 					/* Timeout during requests */
