Skip to content

Commit 0348583

Browse files
committed
Use strnlen() for some string width calculations
Specifically in these functions: Action_setScreenTab() TextMeterMode_draw() LEDMeterMode_draw() RowField_keyAt() drawTab() (ScreenManager.c) The strnlen() function does not calculate true display widths of the Unicode strings, but at least it works with ASCII strings. The function that can calculate display widths of Unicode strings is yet to be implemented. The goal of this commit is to prevent potential arithmetic overflows when calculating string widths and to allow a safe downcast from 'size_t' to 'int' type. This fixes some of the '-Wshorten-64-to-32' warnings produced by Clang (see issue #1673) as a result. Signed-off-by: Kang-Che Sung <[email protected]>
1 parent 29f0dff commit 0348583

File tree

4 files changed

+29
-22
lines changed

4 files changed

+29
-22
lines changed

Action.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -402,19 +402,27 @@ static Htop_Reaction actionPrevScreen(State* st) {
402402

403403
Htop_Reaction Action_setScreenTab(State* st, int x) {
404404
Settings* settings = st->host->settings;
405-
int s = SCREEN_TAB_MARGIN_LEFT;
405+
406+
if (x < SCREEN_TAB_MARGIN_LEFT) {
407+
return 0;
408+
}
409+
410+
int rem = x - SCREEN_TAB_MARGIN_LEFT;
406411
for (unsigned int i = 0; i < settings->nScreens; i++) {
407-
if (x < s) {
408-
return 0;
409-
}
410412
const char* tab = settings->screens[i]->heading;
411-
int len = strlen(tab);
412-
if (x < s + len + 2) {
413+
int width = rem >= 2 ? (int)strnlen(tab, (unsigned int)(rem - 2 + 1)) : 0;
414+
if (rem - 2 < width) {
413415
settings->ssIndex = i;
414416
setActiveScreen(settings, st, i);
415417
return HTOP_UPDATE_PANELHDR | HTOP_REFRESH | HTOP_REDRAW_BAR;
416418
}
417-
s += len + 2 + SCREEN_TAB_COLUMN_GAP;
419+
420+
rem = rem - 2 - width;
421+
if (rem < SCREEN_TAB_COLUMN_GAP) {
422+
return 0;
423+
}
424+
425+
rem -= SCREEN_TAB_COLUMN_GAP;
418426
}
419427
return 0;
420428
}

Meter.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ static void TextMeterMode_draw(Meter* this, int x, int y, int w) {
6060
}
6161
attrset(CRT_colors[RESET_COLOR]);
6262

63-
int captionLen = strlen(caption);
64-
w -= captionLen;
65-
if (w < 1) {
63+
int captionWidth = w >= 1 ? (int)strnlen(caption, w) : 0;
64+
if (w <= captionWidth) {
6665
return;
6766
}
68-
x += captionLen;
67+
w -= captionWidth;
68+
x += captionWidth;
6969

7070
RichString_begin(out);
7171
Meter_displayBuffer(this, &out);
@@ -340,11 +340,11 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
340340
mvaddnstr(yText, x, caption, w);
341341
}
342342

343-
int captionLen = strlen(caption);
344-
if (w <= captionLen) {
343+
int captionWidth = w >= 1 ? (int)strnlen(caption, w) : 0;
344+
if (w <= captionWidth) {
345345
goto end;
346346
}
347-
int xx = x + captionLen;
347+
int xx = x + captionWidth;
348348

349349
#ifdef HAVE_LIBNCURSESW
350350
if (CRT_utf8)

Row.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,13 @@ const char* RowField_alignedTitle(const Settings* settings, RowField field) {
179179
RowField RowField_keyAt(const Settings* settings, int at) {
180180
const RowField* fields = (const RowField*) settings->ss->fields;
181181
RowField field;
182-
int x = 0;
182+
int rem = at;
183183
for (int i = 0; (field = fields[i]); i++) {
184-
int len = strlen(RowField_alignedTitle(settings, field));
185-
if (at >= x && at <= x + len) {
184+
int len = rem > 0 ? (int)strnlen(RowField_alignedTitle(settings, field), rem) : 0;
185+
if (rem <= len) {
186186
return field;
187187
}
188-
x += len;
188+
rem -= len;
189189
}
190190
return COMM;
191191
}

ScreenManager.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,10 @@ static inline bool drawTab(const int* y, int* x, int l, const char* name, bool c
166166
(*x)++;
167167
if (*x >= l)
168168
return false;
169-
int nameLen = strlen(name);
170-
int n = MINIMUM(l - *x, nameLen);
169+
int nameWidth = (int)strnlen(name, l - *x);
171170
attrset(CRT_colors[cur ? SCREENS_CUR_TEXT : SCREENS_OTH_TEXT]);
172-
mvaddnstr(*y, *x, name, n);
173-
*x += n;
171+
mvaddnstr(*y, *x, name, nameWidth);
172+
*x += nameWidth;
174173
if (*x >= l)
175174
return false;
176175
attrset(CRT_colors[cur ? SCREENS_CUR_BORDER : SCREENS_OTH_BORDER]);

0 commit comments

Comments
 (0)