summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2025-02-25 21:58:22 -0500
committergithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2025-02-26 11:53:08 +0000
commit28a8d59cc714aec5c1ceda3db88eb6097f4cf8f0 (patch)
tree08df5f7658e1b868ea9e835b7ccd7deac1f5c6e9
parent3c57ee079dcd89b999dde0fe429682206511493f (diff)
fix(vim_snprintf): special-case handling of binary format
A binary format spec always expects a corresponding unsigned long long value. However, that explicit handling didn't get included when porting the code from Vim, so binary format spec was falling through to the "unsigned" and "length_modifier = NUL" portion of the code: } else { // unsigned switch (length_modifier) { case NUL: uarg = (tvs ? (unsigned)tv_nr(tvs, &arg_idx) : (skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur, fmt), va_arg(ap, unsigned))); break; This incorrectly read an "unsigned" value from an "unsigned long long" variable, which would produce incorrect results on certain platforms. (cherry picked from commit 453f2c52d29143af71436c7c7add52edc9af3bf3)
-rw-r--r--src/nvim/strings.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 097c7c6ae7..5e3f735190 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -1677,8 +1677,6 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st
}
switch (fmt_spec) {
- case 'b':
- case 'B':
case 'd':
case 'u':
case 'o':
@@ -1802,6 +1800,13 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap_st
if (ptr_arg) {
arg_sign = 1;
}
+ } else if (fmt_spec == 'b' || fmt_spec == 'B') {
+ uarg = (tvs
+ ? (unsigned long long)tv_nr(tvs, &arg_idx) // NOLINT(runtime/int)
+ : (skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
+ &arg_cur, fmt),
+ va_arg(ap, unsigned long long))); // NOLINT(runtime/int)
+ arg_sign = (uarg != 0);
} else if (fmt_spec == 'd') {
// signed
switch (length_modifier) {