>From 47423f0603f2ecfb78352be5477fb02c44f1fd35 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 7 Dec 2017 18:07:54 -0800 Subject: [PATCH] Fix zero-padding bug with (format "%#08x" n) Problem reported by Gustaf Waldemarson (Bug#29609). * src/editfns.c (styled_format): Put zero padding after a leading "0x", not before. * test/src/editfns-tests.el (format-sharp-0-x): New test. --- src/editfns.c | 24 ++++++++++++++++-------- test/src/editfns-tests.el | 6 ++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/editfns.c b/src/editfns.c index e671ba0..ebf6518 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -4722,11 +4722,19 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) char src0 = src[0]; int exponent_bytes = 0; bool signedp = src0 == '-' || src0 == '+' || src0 == ' '; - unsigned char after_sign = src[signedp]; - if (zero_flag && 0 <= char_hexdigit (after_sign)) + int prefix_bytes = (signedp + + ((src[signedp] == '0' + && (src[signedp + 1] == 'x' + || src[signedp + 1] == 'X')) + ? 2 : 0)); + if (zero_flag) { - leading_zeros += padding; - padding = 0; + unsigned char after_prefix = src[prefix_bytes]; + if (0 <= char_hexdigit (after_prefix)) + { + leading_zeros += padding; + padding = 0; + } } if (excess_precision @@ -4745,13 +4753,13 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) nchars += padding; } - *p = src0; - src += signedp; - p += signedp; + memcpy (p, src, prefix_bytes); + p += prefix_bytes; + src += prefix_bytes; memset (p, '0', leading_zeros); p += leading_zeros; int significand_bytes - = sprintf_bytes - signedp - exponent_bytes; + = sprintf_bytes - prefix_bytes - exponent_bytes; memcpy (p, src, significand_bytes); p += significand_bytes; src += significand_bytes; diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index 70dc937..283a642 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el @@ -136,6 +136,12 @@ transpose-test-get-byte-positions (ert-deftest format-c-float () (should-error (format "%c" 0.5))) +;;; Test for Bug#29609. +(ert-deftest format-sharp-0-x () + (should (string-equal (format "%#08x" #x10) "0x000010")) + (should (string-equal (format "%#05X" #x10) "0X010")) + (should (string-equal (format "%#04x" 0) "0000"))) + ;;; Check format-time-string with various TZ settings. ;;; Use only POSIX-compatible TZ values, since the tests should work ;;; even if tzdb is not in use. -- 2.7.4