aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2017-12-07 18:07:54 -0800
committerPaul Eggert2017-12-07 18:08:56 -0800
commit47423f0603f2ecfb78352be5477fb02c44f1fd35 (patch)
tree78c40843566e2464c5d84dd12d4057d064b768e3
parentd4db37b283daffa0f8c942a5b526b6444edc34c5 (diff)
downloademacs-47423f0603f2ecfb78352be5477fb02c44f1fd35.tar.gz
emacs-47423f0603f2ecfb78352be5477fb02c44f1fd35.zip
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.
-rw-r--r--src/editfns.c24
-rw-r--r--test/src/editfns-tests.el6
2 files changed, 22 insertions, 8 deletions
diff --git a/src/editfns.c b/src/editfns.c
index e671ba0761c..ebf6518994b 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -4722,11 +4722,19 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4722 char src0 = src[0]; 4722 char src0 = src[0];
4723 int exponent_bytes = 0; 4723 int exponent_bytes = 0;
4724 bool signedp = src0 == '-' || src0 == '+' || src0 == ' '; 4724 bool signedp = src0 == '-' || src0 == '+' || src0 == ' ';
4725 unsigned char after_sign = src[signedp]; 4725 int prefix_bytes = (signedp
4726 if (zero_flag && 0 <= char_hexdigit (after_sign)) 4726 + ((src[signedp] == '0'
4727 && (src[signedp + 1] == 'x'
4728 || src[signedp + 1] == 'X'))
4729 ? 2 : 0));
4730 if (zero_flag)
4727 { 4731 {
4728 leading_zeros += padding; 4732 unsigned char after_prefix = src[prefix_bytes];
4729 padding = 0; 4733 if (0 <= char_hexdigit (after_prefix))
4734 {
4735 leading_zeros += padding;
4736 padding = 0;
4737 }
4730 } 4738 }
4731 4739
4732 if (excess_precision 4740 if (excess_precision
@@ -4745,13 +4753,13 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4745 nchars += padding; 4753 nchars += padding;
4746 } 4754 }
4747 4755
4748 *p = src0; 4756 memcpy (p, src, prefix_bytes);
4749 src += signedp; 4757 p += prefix_bytes;
4750 p += signedp; 4758 src += prefix_bytes;
4751 memset (p, '0', leading_zeros); 4759 memset (p, '0', leading_zeros);
4752 p += leading_zeros; 4760 p += leading_zeros;
4753 int significand_bytes 4761 int significand_bytes
4754 = sprintf_bytes - signedp - exponent_bytes; 4762 = sprintf_bytes - prefix_bytes - exponent_bytes;
4755 memcpy (p, src, significand_bytes); 4763 memcpy (p, src, significand_bytes);
4756 p += significand_bytes; 4764 p += significand_bytes;
4757 src += significand_bytes; 4765 src += significand_bytes;
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el
index 70dc9372fad..283a642dd97 100644
--- a/test/src/editfns-tests.el
+++ b/test/src/editfns-tests.el
@@ -136,6 +136,12 @@
136(ert-deftest format-c-float () 136(ert-deftest format-c-float ()
137 (should-error (format "%c" 0.5))) 137 (should-error (format "%c" 0.5)))
138 138
139;;; Test for Bug#29609.
140(ert-deftest format-sharp-0-x ()
141 (should (string-equal (format "%#08x" #x10) "0x000010"))
142 (should (string-equal (format "%#05X" #x10) "0X010"))
143 (should (string-equal (format "%#04x" 0) "0000")))
144
139;;; Check format-time-string with various TZ settings. 145;;; Check format-time-string with various TZ settings.
140;;; Use only POSIX-compatible TZ values, since the tests should work 146;;; Use only POSIX-compatible TZ values, since the tests should work
141;;; even if tzdb is not in use. 147;;; even if tzdb is not in use.