[openssh-commits] [openssh] 02/02: sync fmt_scaled.c with OpenBSD upstream

git+noreply at mindrot.org git+noreply at mindrot.org
Sun Jun 7 09:57:15 AEST 2026


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 47af21eb8d480c0f368a629ab58e31b993ed28f2
Author: Damien Miller <djm at mindrot.org>
AuthorDate: Sun Jun 7 09:56:41 2026 +1000

    sync fmt_scaled.c with OpenBSD upstream
    
    Notably picks up this commit:
    
    revision 1.24
    date: 2026/06/06 23:49:25;  author: djm;  state: Exp;  lines: +28 -12;  commitid: oznzDs0MaUT3FEqO;
    rearrange scan_scaled(3) ordering of multiplications and divisions
    to better preserve accuracy for large exponents. From metsw24-max
    via https://github.com/openssh/openssh-portable/pull/671/
    
    ok tb@
---
 openbsd-compat/fmt_scaled.c | 39 +++++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/openbsd-compat/fmt_scaled.c b/openbsd-compat/fmt_scaled.c
index 87d40d2d3..9aa8ef23a 100644
--- a/openbsd-compat/fmt_scaled.c
+++ b/openbsd-compat/fmt_scaled.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fmt_scaled.c,v 1.21 2022/03/11 07:29:53 dtucker Exp $	*/
+/*	$OpenBSD: fmt_scaled.c,v 1.25 2026/06/06 23:53:59 djm Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002, 2003 Ian F. Darwin.  All rights reserved.
@@ -77,7 +77,7 @@ scan_scaled(char *scaled, long long *result)
 {
 	char *p = scaled;
 	int sign = 0;
-	unsigned int i, ndigits = 0, fract_digits = 0;
+	unsigned int i, ndigits = 0, fract_digits = 0, muls = 0, divs = 0;
 	long long scale_fact = 1, whole = 0, fpart = 0;
 
 	/* Skip leading whitespace */
@@ -186,18 +186,33 @@ scan_scaled(char *scaled, long long *result)
 			/* scale whole part */
 			whole *= scale_fact;
 
-			/* truncate fpart so it doesn't overflow.
-			 * then scale fractional part.
+			/*
+			 * Scale fractional part: compute
+			 *   fpart * scale_fact / 10^(fract_digits-1)
+			 * without intermediate overflow. scale_fact is 1024^i,
+			 * i.e. a power of 1024 = 2^10. Interleave
+			 * multiply-by-1024 with divide-by-10 so the running
+			 * value stays within long long range while preserving
+			 * precision.
 			 */
-			while (fpart >= LLONG_MAX / scale_fact ||
-			    fpart <= LLONG_MIN / scale_fact) {
-				fpart /= 10;
-				fract_digits--;
-			}
-			fpart *= scale_fact;
-			if (fract_digits > 0) {
-				for (i = 0; i < fract_digits -1; i++)
+			muls = i;
+			divs = fract_digits > 0 ?  fract_digits - 1 : 0;
+			while (muls > 0 && divs > 0) {
+				if (fpart <= LLONG_MAX / 1024) {
+					fpart *= 1024;
+					muls--;
+				} else {
 					fpart /= 10;
+					divs--;
+				}
+			}
+			while (muls > 0) {
+				fpart *= 1024;
+				muls--;
+			}
+			while (divs > 0) {
+				fpart /= 10;
+				divs--;
 			}
 			if (sign == -1)
 				whole -= fpart;

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list