diff options
| author | Paul Eggert | 2023-05-17 15:07:38 -0700 |
|---|---|---|
| committer | Paul Eggert | 2023-05-17 15:41:00 -0700 |
| commit | afbdae00ab59bbda971780fa04dd75dc7d1e7df7 (patch) | |
| tree | a847a84dd9fe028c83db27eda0901cd45ed683ad /lib/nstrftime.c | |
| parent | 0bba1b8c3df8b7b53e08fd69dcc832d253e7a2d1 (diff) | |
| download | emacs-afbdae00ab59bbda971780fa04dd75dc7d1e7df7.tar.gz emacs-afbdae00ab59bbda971780fa04dd75dc7d1e7df7.zip | |
Update from Gnulib by running admin/merge-gnulib
Diffstat (limited to 'lib/nstrftime.c')
| -rw-r--r-- | lib/nstrftime.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/lib/nstrftime.c b/lib/nstrftime.c index 68bb560910d..2a1dd8d88d7 100644 --- a/lib/nstrftime.c +++ b/lib/nstrftime.c | |||
| @@ -62,6 +62,7 @@ extern char *tzname[]; | |||
| 62 | #endif | 62 | #endif |
| 63 | 63 | ||
| 64 | #include <limits.h> | 64 | #include <limits.h> |
| 65 | #include <stdckdint.h> | ||
| 65 | #include <stddef.h> | 66 | #include <stddef.h> |
| 66 | #include <stdlib.h> | 67 | #include <stdlib.h> |
| 67 | #include <string.h> | 68 | #include <string.h> |
| @@ -226,15 +227,6 @@ extern char *tzname[]; | |||
| 226 | # undef __mbsrtowcs_l | 227 | # undef __mbsrtowcs_l |
| 227 | # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st) | 228 | # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st) |
| 228 | # endif | 229 | # endif |
| 229 | # define widen(os, ws, l) \ | ||
| 230 | { \ | ||
| 231 | mbstate_t __st; \ | ||
| 232 | const char *__s = os; \ | ||
| 233 | memset (&__st, '\0', sizeof (__st)); \ | ||
| 234 | l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \ | ||
| 235 | ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \ | ||
| 236 | (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \ | ||
| 237 | } | ||
| 238 | #endif | 230 | #endif |
| 239 | 231 | ||
| 240 | 232 | ||
| @@ -684,8 +676,8 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) | |||
| 684 | width = 0; | 676 | width = 0; |
| 685 | do | 677 | do |
| 686 | { | 678 | { |
| 687 | if (INT_MULTIPLY_WRAPV (width, 10, &width) | 679 | if (ckd_mul (&width, width, 10) |
| 688 | || INT_ADD_WRAPV (width, *f - L_('0'), &width)) | 680 | || ckd_add (&width, width, *f - L_('0'))) |
| 689 | width = INT_MAX; | 681 | width = INT_MAX; |
| 690 | ++f; | 682 | ++f; |
| 691 | } | 683 | } |
| @@ -1374,11 +1366,31 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) | |||
| 1374 | #ifdef COMPILE_WIDE | 1366 | #ifdef COMPILE_WIDE |
| 1375 | { | 1367 | { |
| 1376 | /* The zone string is always given in multibyte form. We have | 1368 | /* The zone string is always given in multibyte form. We have |
| 1377 | to transform it first. */ | 1369 | to convert it to wide character. */ |
| 1378 | wchar_t *wczone; | 1370 | size_t w = pad == L_('-') || width < 0 ? 0 : width; |
| 1379 | size_t len; | 1371 | char const *z = zone; |
| 1380 | widen (zone, wczone, len); | 1372 | mbstate_t st = {0}; |
| 1381 | cpy (len, wczone); | 1373 | size_t len = __mbsrtowcs_l (p, &z, maxsize - i, &st, loc); |
| 1374 | if (len == (size_t) -1) | ||
| 1375 | return 0; | ||
| 1376 | size_t incr = len < w ? w : len; | ||
| 1377 | if (incr >= maxsize - i) | ||
| 1378 | { | ||
| 1379 | errno = ERANGE; | ||
| 1380 | return 0; | ||
| 1381 | } | ||
| 1382 | if (p) | ||
| 1383 | { | ||
| 1384 | if (len < w) | ||
| 1385 | { | ||
| 1386 | size_t delta = w - len; | ||
| 1387 | wmemmove (p + delta, p, len); | ||
| 1388 | wchar_t wc = pad == L_('0') || pad == L_('+') ? L'0' : L' '; | ||
| 1389 | wmemset (p, wc, delta); | ||
| 1390 | } | ||
| 1391 | p += incr; | ||
| 1392 | } | ||
| 1393 | i += incr; | ||
| 1382 | } | 1394 | } |
| 1383 | #else | 1395 | #else |
| 1384 | cpy (strlen (zone), zone); | 1396 | cpy (strlen (zone), zone); |