fix: silence sign-compare and format-truncation warnings

Release builds (gcc 16, -O2) warned in three spots; debug builds only showed the first:

- thumb_extent_iter: copy tex->width/height (uint32_t) into int locals
  after the zero guard so all extent math is int<->int.
- dump_path call sites: grow cpath/path buffers 512 -> 1024. Worst
  case is ~535 bytes (dump_dir[512] + kind + seq), so gcc can prove
  no truncation at every inlined site.
- overlay_find_icon_file: skip overlong XDG roots via snprintf return
  checks, fail fast on icon names >1024 chars (can never match a real
  file component), and use %.1024s plus truncation guards in both
  probe loops (worst case ~1.6k < 4096).

No behaviour change on sane inputs: truncated probes previously just
failed access()/fopen(); now they are skipped explicitly.

Verified: full rebuilds of build/ and build-release/ compile with zero
warnings; toplevel_icon_preferred, sigusr1_dumps and
overlay_no_needless_ellipsis pass.
This commit is contained in:
Andrew Hamilton 2026-09-30 08:07:39 +10:00
parent 9d1abe2e86
commit 1c1bc5a230

50
kick.c
View file

@ -2180,16 +2180,23 @@ static char *overlay_find_icon_file(const char *name) {
int n_roots = 0;
const char *data_home = getenv("XDG_DATA_HOME");
const char *data_dirs = getenv("XDG_DATA_DIRS");
if (data_home && data_home[0] && n_roots < 8)
snprintf(roots[n_roots++], sizeof(roots[0]), "%s/icons", data_home);
if (data_home && data_home[0] && n_roots < 8) {
int n = snprintf(roots[n_roots], sizeof(roots[0]), "%s/icons",
data_home);
if (n > 0 && (size_t)n < sizeof(roots[0]))
n_roots++;
}
if (!data_dirs || !data_dirs[0])
data_dirs = "/usr/local/share:/usr/share";
char *copy = strdup(data_dirs);
for (char *p = copy, *dir; p && n_roots < 8; p = dir) {
dir = strchr(p, ':');
if (dir) *dir++ = '\0';
if (p[0])
snprintf(roots[n_roots++], sizeof(roots[0]), "%s/icons", p);
if (p[0]) {
int n = snprintf(roots[n_roots], sizeof(roots[0]), "%s/icons", p);
if (n > 0 && (size_t)n < sizeof(roots[0]))
n_roots++;
}
}
free(copy);
@ -2198,13 +2205,22 @@ static char *overlay_find_icon_file(const char *name) {
overlay_endswith(name, ".svg")))
return strdup(name);
/* Icon names become a single path component below; anything absurdly
long can never match a real file, so fail fast instead of probing
a truncated path. The %.1024s bound keeps every snprintf below
provably within buf (worst case ~1.6k < 4096). */
if (strlen(name) > 1024)
return NULL;
char buf[4096];
for (int tr = 0; tr < n_roots; tr++) {
for (size_t t = 0; t < sizeof(themes) / sizeof(themes[0]); t++) {
for (size_t s = 0; s < sizeof(sizes) / sizeof(sizes[0]); s++) {
for (size_t e = 0; e < sizeof(exts) / sizeof(exts[0]); e++) {
snprintf(buf, sizeof(buf), "%s/%s/%s/apps/%s.%s",
int n = snprintf(buf, sizeof(buf), "%s/%s/%s/apps/%.1024s.%s",
roots[tr], themes[t], sizes[s], name, exts[e]);
if (n < 0 || (size_t)n >= sizeof(buf))
continue;
if (access(buf, R_OK) == 0)
return strdup(buf);
}
@ -2216,7 +2232,9 @@ static char *overlay_find_icon_file(const char *name) {
};
for (size_t pr = 0; pr < sizeof(pixmap_roots) / sizeof(pixmap_roots[0]); pr++) {
for (size_t e = 0; e < sizeof(exts) / sizeof(exts[0]); e++) {
snprintf(buf, sizeof(buf), "%s/%s.%s", pixmap_roots[pr], name, exts[e]);
int n = snprintf(buf, sizeof(buf), "%s/%.1024s.%s", pixmap_roots[pr], name, exts[e]);
if (n < 0 || (size_t)n >= sizeof(buf))
continue;
if (access(buf, R_OK) == 0)
return strdup(buf);
}
@ -2891,19 +2909,21 @@ static void thumb_extent_iter(struct wlr_surface *surface, int sx, int sy,
void *data) {
struct thumb_extent *e = data;
struct wlr_texture *tex = surface ? wlr_surface_get_texture(surface) : NULL;
if (!tex || tex->width <= 0 || tex->height <= 0) return;
if (!tex || tex->width == 0 || tex->height == 0) return;
int tw = (int)tex->width;
int th = (int)tex->height;
if (!e->any) {
e->minx = sx;
e->miny = sy;
e->maxx = sx + tex->width;
e->maxy = sy + tex->height;
e->maxx = sx + tw;
e->maxy = sy + th;
e->any = true;
return;
}
if (sx < e->minx) e->minx = sx;
if (sy < e->miny) e->miny = sy;
if (sx + tex->width > e->maxx) e->maxx = sx + tex->width;
if (sy + tex->height > e->maxy) e->maxy = sy + tex->height;
if (sx + tw > e->maxx) e->maxx = sx + tw;
if (sy + th > e->maxy) e->maxy = sy + th;
}
static void thumb_draw_iter(struct wlr_surface *surface, int sx, int sy,
@ -4950,7 +4970,7 @@ static void handle_toplevel_commit(struct wl_listener *listener, void *data) {
"nonblack=%lu/%lu mean=%lu\n", fmt, nonblack,
(unsigned long)bw * bh,
lum / ((unsigned long)bw * bh + 1));
char cpath[512];
char cpath[1024];
dump_path(cpath, sizeof(cpath), "client", dump_seq);
FILE *cf = fopen(cpath, "wb");
if (cf) {
@ -9869,7 +9889,7 @@ static void dump_scene_buffer(struct wlr_buffer *buf) {
kick_log(KICK_LOG_INFO, "[dump] scene %dx%d fmt=0x%x "
"nonblack=%lu/%lu mean=%lu\n", w, h, format, nonblack,
(unsigned long)w * h, lum / ((unsigned long)w * h + 1));
char path[512];
char path[1024];
dump_path(path, sizeof(path), "scene", dump_seq);
FILE *f = fopen(path, "wb");
if (f) {
@ -9912,7 +9932,7 @@ static void dump_host_back(void) {
kick_log(KICK_LOG_INFO, "[dump] host %dx%d nonblack=%lu/%lu mean=%lu\n",
w, h, nonblack, (unsigned long)w * h,
lum / ((unsigned long)w * h + 1));
char path[512];
char path[1024];
dump_path(path, sizeof(path), "host", dump_seq);
FILE *f = fopen(path, "wb");
if (f) {
@ -9983,7 +10003,7 @@ static void dump_standalone_buffer(struct wlr_buffer *buf) {
kick_log(KICK_LOG_INFO, "[dump] host %dx%d nonblack=%lu/%lu mean=%lu\n",
w, h, nonblack, (unsigned long)w * h,
lum / ((unsigned long)w * h + 1));
char path[512];
char path[1024];
dump_path(path, sizeof(path), "host", dump_seq);
FILE *f = fopen(path, "wb");
if (f) {