[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