#include "osc.h" #include "../internal.h" #include #include static int b64_val(char c) { if (c >= 'A' && c <= 'Z') return c - 'A'; if (c >= 'a' && c <= 'z') return c - 'a' + 26; if (c >= '0' && c <= '9') return c - '0' + 52; if (c == '+') return 62; if (c == '/') return 63; return -1; } static bool b64_decode(const char *s, size_t n, char *out, size_t *out_len) { size_t pad = 0; while (pad < n && s[n - pad - 1] == '=') pad++; n -= pad; if (pad > 2 || (pad && n % 4 + pad != 4)) return false; size_t rem = n % 4; if (rem == 1) return false; size_t i = 0, o = 0; for (; i + 4 <= n; i += 4) { int a = b64_val(s[i]), b = b64_val(s[i + 1]); int c = b64_val(s[i + 2]), d = b64_val(s[i + 3]); if ((a | b | c | d) < 0) return false; out[o++] = (char)(a << 2 | b >> 4); out[o++] = (char)(b << 4 | c >> 2); out[o++] = (char)(c << 6 | d); } if (rem >= 2) { int a = b64_val(s[i]), b = b64_val(s[i + 1]); if ((a | b) < 0) return false; out[o++] = (char)(a << 2 | b >> 4); if (rem == 3) { int c = b64_val(s[i + 2]); if (c < 0) return false; out[o++] = (char)(b << 4 | c >> 2); } } *out_len = o; return true; } void term_osc52(struct term *t, const char *params) { const char *sep = strchr(params, ';'); if (!sep || sep == params) return; const char *pd = sep + 1; if (!strcmp(pd, "?") || !t->cb.clipboard) return; size_t sel_len = (size_t)(sep - params); char sel[64]; if (sel_len >= sizeof(sel)) return; memcpy(sel, params, sel_len); sel[sel_len] = '\0'; if (!*pd) { t->cb.clipboard(t->cb.ud, sel, "", 0); return; } size_t enc_len = strlen(pd); char *dec = (char *)pd; size_t dec_len; if (b64_decode(pd, enc_len, dec, &dec_len)) t->cb.clipboard(t->cb.ud, sel, dec, dec_len); }