From 281cff0b604735407e1ffbee439086c8780b2f65 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 3 Apr 2026 21:13:41 +0530 Subject: [PATCH] base64 decode present dnd source data --- kitty/base64.h | 12 ++++++++++++ kitty/dnd.c | 9 +++++++-- kitty/state.h | 5 ++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/kitty/base64.h b/kitty/base64.h index 331443763..bef8b8ad8 100644 --- a/kitty/base64.h +++ b/kitty/base64.h @@ -10,9 +10,21 @@ #include #include "../3rdparty/base64/include/libbase64.h" +typedef struct base64_state base64_state; + static inline size_t required_buffer_size_for_base64_decode(size_t src_sz) { return (src_sz / 4 * 3 + 2); } static inline size_t required_buffer_size_for_base64_encode(size_t src_sz) { return ((src_sz + 2) / 3 * 4); } +static inline void +base64_init_stream_decoder(base64_state *state) { + base64_stream_decode_init(state, 0); +} + +static inline bool +base64_decode_stream(base64_state *state, const uint8_t *src, size_t src_sz, uint8_t *dest, size_t *dest_sz) { + if (*dest_sz < required_buffer_size_for_base64_decode(src_sz)) return false; + return base64_stream_decode(state, (const char*)src, src_sz, (char*)dest, dest_sz) == 1; +} static inline bool base64_decode8(const uint8_t *src, size_t src_sz, uint8_t *dest, size_t *dest_sz) { diff --git a/kitty/dnd.c b/kitty/dnd.c index 7f68dd8f1..306294612 100644 --- a/kitty/dnd.c +++ b/kitty/dnd.c @@ -912,14 +912,19 @@ drag_add_pre_sent_data(Window *w, unsigned idx, const uint8_t *payload, size_t s if (sz + ds.pre_sent_total_sz > 64 * 1024 * 1024) abrt(EFBIG); ds.pre_sent_total_sz += sz; DragSourceItem *item = ds.items + idx; + if (!item->data_decode_initialized) { + item->data_decode_initialized = true; + base64_init_stream_decoder(&item->base64_state); + } if (item->data_capacity < sz + item->data_size) { size_t newcap = MAX(item->data_size * 2, sz + item->data_size); item->optional_data = realloc(item->optional_data, newcap); if (!item->optional_data) abrt(ENOMEM); item->data_capacity = newcap; } - memcpy(item->optional_data + item->data_size, payload, sz); - item->data_size += sz; + size_t outlen = item->data_capacity - item->data_size; + if (!base64_decode_stream(&item->base64_state, payload, sz, item->optional_data + item->data_size, &outlen)) abrt(EINVAL); + item->data_size += outlen; } #undef abrt diff --git a/kitty/state.h b/kitty/state.h index 7524d0eb8..68025b262 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -10,6 +10,7 @@ #include "screen.h" #include "monotonic.h" #include "window_logo.h" +#include "base64.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #include @@ -235,8 +236,10 @@ typedef struct DirHandle { typedef struct DragSourceItem { const char *mime_type; - char *optional_data; + uint8_t *optional_data; size_t data_size, data_capacity; + base64_state base64_state; + bool data_decode_initialized; } DragSourceItem; typedef struct Window {