#include "bar/util.h" #include #include #include constexpr char TRUNCATION_SUFFIX[] = "…"; static inline bool is_utf8_continuation(char c) { return (c & 0xC0) == 0x80; } void sanitise_text(char *dst, const char *src, size_t dst_size) { if (dst_size == 0) return; if (!src) src = ""; size_t dst_len = 0; size_t max_len = dst_size - 1; while (*src != '\0' && dst_len < max_len) { unsigned char unit = (unsigned char)*src; if ((unit >= 0x20 && unit != 0x7f) || unit > 0x7f) { dst[dst_len++] = (char)unit; } src++; } dst[dst_len] = '\0'; } void truncate_string(char *dst, const char *src, size_t dst_size) { if (dst_size == 0) return; size_t src_len = strlen(src); if (src_len < dst_size) { strcpy(dst, src); return; } if (dst_size <= sizeof TRUNCATION_SUFFIX) { dst[0] = '\0'; return; } size_t cutoff = dst_size - sizeof TRUNCATION_SUFFIX - 2; while (cutoff > 0 && is_utf8_continuation(src[cutoff])) { cutoff--; } if (cutoff > 0 && (src[cutoff] & 0x80) != 0) { cutoff--; } while (cutoff > 0 && src[cutoff - 1] == ' ') { cutoff--; } if (cutoff > 0) { memcpy(dst, src, cutoff); } memcpy(dst + cutoff, TRUNCATION_SUFFIX, sizeof TRUNCATION_SUFFIX - 1); dst[cutoff + sizeof TRUNCATION_SUFFIX - 1] = '\0'; } void sanitise_and_truncate(char *dst, const char *src, size_t dst_size) { if (dst_size == 0) return; if (!src) { dst[0] = '\0'; return; } size_t len = strlen(src); char *temp = malloc(len + 1); if (!temp) { dst[0] = '\0'; return; } sanitise_text(temp, src, len + 1); truncate_string(dst, temp, dst_size); free(temp); } void assign_and_truncate(char **dst, const char *src, size_t max_len) { if (!src) { free(*dst); *dst = nullptr; return; } size_t src_len = strlen(src); size_t copy_len = (src_len > max_len) ? max_len : src_len; char *temp = malloc(copy_len + 1); if (!temp) { return; } sanitise_and_truncate(temp, src, copy_len + 1); free(*dst); *dst = temp; } inline void assign_str(char **dst, const char *src) { if (*dst == src) return; char *new_str = src ? strdup(src) : nullptr; free(*dst); *dst = new_str; } bool read_exact(int fd, void *buf, size_t n) { size_t done = 0; while (done < n) { ssize_t r = read(fd, (char *)buf + done, n - done); if (r < 0 && errno == EINTR) continue; if (r <= 0) return false; done += (size_t)r; } return true; } bool write_exact(int fd, const void *buf, size_t n) { size_t done = 0; while (done < n) { ssize_t r = write(fd, (const char *)buf + done, n - done); if (r < 0 && errno == EINTR) continue; if (r <= 0) return false; done += (size_t)r; } return true; }