Root cause: etcp_on_up/etcp_on_down/etcp_conn_process_send_queue used fixed buffers (links_str[256], l_status[256]) with snprintf chains in loops over links. With 15+ links (IPv6 addresses), sizeof(buf)-offset turned negative → vsnprintf size=(size_t)(-17) → FORTIFY abort on Bionic. Fixes: - lib/strbuf.h/c: safe growable printf buffer (auto-realloc) - etcp.c: 3 snprintf chains → strbuf - debug_config.c: BUF_ADVANCE macro prevents offset overflow - android_jni_bridge.c: bridge_log va_list fix, set_member_flags guard - chat_core.c: TAGS_ADVANCE macro in tags_commit - AndroidManifest.xml: dataSync→specialUse (time limit exhausted) - stcp: ed25519 pubkey exchange, tcp link addr/status in JNI bridge - etcp_router: encrypted flag + ECDH per peer-pair - node_conn_direct: TCP link support - topo_node: group nodes cleanup - media_delivery: buffer overflow fix - test_stcp: ed25519 key exchange test - tests: invite_group_create + Makefile update
51 lines
1.6 KiB
C
51 lines
1.6 KiB
C
/*
|
|
* strbuf.h — safe growable printf buffer
|
|
*
|
|
* Replaces snprintf(buf+off, sizeof(buf)-off, ...) chains that crash
|
|
* on overflow (snprintf returns un-truncated size, offset exceeds buffer,
|
|
* next call gets negative size → FORTIFY abort on Bionic/Android).
|
|
*
|
|
* Usage:
|
|
* struct strbuf sb = strbuf_new();
|
|
* strbuf_addf(&sb, "{\"ver\":\"%d\"", ver);
|
|
* strbuf_addf(&sb, ",\"name\":\"%s\"", name);
|
|
* strbuf_addf(&sb, "}");
|
|
* // use strbuf_str(&sb) or strbuf_detach(&sb)
|
|
* strbuf_free(&sb);
|
|
*/
|
|
#ifndef STRBUF_H
|
|
#define STRBUF_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdarg.h>
|
|
|
|
struct strbuf {
|
|
char *buf; /* allocated buffer, always null-terminated */
|
|
size_t cap; /* total capacity (including '\0') */
|
|
size_t len; /* current length (excluding '\0') */
|
|
};
|
|
|
|
/* zero-init on stack: struct strbuf sb = {0}; */
|
|
#define strbuf_new() ((struct strbuf){NULL, 0, 0})
|
|
|
|
void strbuf_init(struct strbuf *sb, size_t initial_cap);
|
|
void strbuf_free(struct strbuf *sb);
|
|
|
|
/* returns buf and detaches — caller must u_free(). sb is reset to empty */
|
|
char *strbuf_detach(struct strbuf *sb);
|
|
|
|
/* reset len=0, keep allocation */
|
|
void strbuf_reset(struct strbuf *sb);
|
|
|
|
/* printf-like append. auto-grows. returns written bytes or -1 on OOM */
|
|
int strbuf_addf(struct strbuf *sb, const char *fmt, ...)
|
|
__attribute__((format(printf, 2, 3)));
|
|
|
|
void strbuf_addc(struct strbuf *sb, char c);
|
|
void strbuf_adds(struct strbuf *sb, const char *s);
|
|
|
|
/* safe accessor — never returns NULL */
|
|
#define strbuf_str(sb) ((sb)->buf ? (sb)->buf : "")
|
|
|
|
#endif /* STRBUF_H */
|