Skip to content

Commit e7a0182

Browse files
authored
Merge pull request #1588 from Explorer09/process-offsets-size-type
Use size_t for Process offset values
2 parents 6f948d3 + 656a2d2 commit e7a0182

File tree

9 files changed

+158
-136
lines changed

9 files changed

+158
-136
lines changed

Process.c

Lines changed: 102 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -64,29 +64,26 @@ void Process_fillStarttimeBuffer(Process* this) {
6464
*/
6565
#define TASK_COMM_LEN 16
6666

67-
static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdlineBasenameStart, int* pCommStart, int* pCommEnd) {
67+
static bool findCommInCmdline(const char* comm, const char* cmdline, size_t cmdlineBasenameStart, size_t* pCommStart, size_t* pCommLen) {
6868
/* Try to find procComm in tokenized cmdline - this might in rare cases
6969
* mis-identify a string or fail, if comm or cmdline had been unsuitably
7070
* modified by the process */
7171
const char* tokenBase;
7272
size_t tokenLen;
7373
const size_t commLen = strlen(comm);
7474

75-
if (cmdlineBasenameStart < 0)
76-
return false;
77-
7875
for (const char* token = cmdline + cmdlineBasenameStart; *token;) {
7976
for (tokenBase = token; *token && *token != '\n'; ++token) {
8077
if (*token == '/') {
8178
tokenBase = token + 1;
8279
}
8380
}
84-
tokenLen = token - tokenBase;
81+
tokenLen = (size_t)(token - tokenBase);
8582

8683
if ((tokenLen == commLen || (tokenLen > commLen && commLen == (TASK_COMM_LEN - 1))) &&
8784
strncmp(tokenBase, comm, commLen) == 0) {
88-
*pCommStart = tokenBase - cmdline;
89-
*pCommEnd = token - cmdline;
85+
*pCommStart = (size_t)(tokenBase - cmdline);
86+
*pCommLen = tokenLen;
9087
return true;
9188
}
9289

@@ -99,15 +96,12 @@ static bool findCommInCmdline(const char* comm, const char* cmdline, int cmdline
9996
return false;
10097
}
10198

102-
static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int cmdlineBaseOffset, const char* exe, int exeBaseOffset, int exeBaseLen) {
103-
int matchLen; /* matching length to be returned */
104-
char delim; /* delimiter following basename */
105-
99+
static size_t matchCmdlinePrefixWithExeSuffix(const char* cmdline, size_t* cmdlineBasenameStart, const char* exe, size_t exeBaseOffset, size_t exeBaseLen) {
106100
/* cmdline prefix is an absolute path: it must match whole exe. */
107101
if (cmdline[0] == '/') {
108-
matchLen = exeBaseLen + exeBaseOffset;
102+
size_t matchLen = exeBaseLen + exeBaseOffset;
109103
if (strncmp(cmdline, exe, matchLen) == 0) {
110-
delim = cmdline[matchLen];
104+
char delim = cmdline[matchLen];
111105
if (delim == 0 || delim == '\n' || delim == ' ') {
112106
return matchLen;
113107
}
@@ -121,35 +115,43 @@ static int matchCmdlinePrefixWithExeSuffix(const char* cmdline, int cmdlineBaseO
121115
* that make htop's identification of the basename in cmdline unreliable.
122116
* For e.g. /usr/libexec/gdm-session-worker modifies its cmdline to
123117
* "gdm-session-worker [pam/gdm-autologin]" and htop ends up with
124-
* proccmdlineBasenameEnd at "gdm-autologin]". This issue could arise with
118+
* cmdlineBasenameStart at "gdm-autologin]". This issue could arise with
125119
* chrome as well as it stores in cmdline its concatenated argument vector,
126120
* without NUL delimiter between the arguments (which may contain a '/')
127121
*
128122
* So if needed, we adjust cmdlineBaseOffset to the previous (if any)
129123
* component of the cmdline relative path, and retry the procedure. */
130-
bool delimFound; /* if valid basename delimiter found */
124+
size_t cmdlineBaseOffset = *cmdlineBasenameStart;
125+
bool delimFound = true; /* if valid basename delimiter found */
131126
do {
132127
/* match basename */
133-
matchLen = exeBaseLen + cmdlineBaseOffset;
128+
size_t matchLen = exeBaseLen + cmdlineBaseOffset;
134129
if (cmdlineBaseOffset < exeBaseOffset &&
135130
strncmp(cmdline + cmdlineBaseOffset, exe + exeBaseOffset, exeBaseLen) == 0) {
136-
delim = cmdline[matchLen];
131+
char delim = cmdline[matchLen];
137132
if (delim == 0 || delim == '\n' || delim == ' ') {
138-
int i, j;
139133
/* reverse match the cmdline prefix and exe suffix */
140-
for (i = cmdlineBaseOffset - 1, j = exeBaseOffset - 1;
141-
i >= 0 && j >= 0 && cmdline[i] == exe[j]; --i, --j)
142-
;
134+
size_t i = cmdlineBaseOffset;
135+
size_t j = exeBaseOffset;
136+
while (i >= 1 && j >= 1 && cmdline[i - 1] == exe[j - 1]) {
137+
--i, --j;
138+
}
143139

144140
/* full match, with exe suffix being a valid relative path */
145-
if (i < 0 && j >= 0 && exe[j] == '/')
141+
if (i < 1 && j >= 1 && exe[j - 1] == '/') {
142+
*cmdlineBasenameStart = cmdlineBaseOffset;
146143
return matchLen;
144+
}
147145
}
148146
}
149147

150148
/* Try to find the previous potential cmdlineBaseOffset - it would be
151149
* preceded by '/' or nothing, and delimited by ' ' or '\n' */
152-
for (delimFound = false, cmdlineBaseOffset -= 2; cmdlineBaseOffset > 0; --cmdlineBaseOffset) {
150+
delimFound = false;
151+
if (cmdlineBaseOffset <= 2) {
152+
return 0;
153+
}
154+
for (cmdlineBaseOffset -= 2; cmdlineBaseOffset > 0; --cmdlineBaseOffset) {
153155
if (delimFound) {
154156
if (cmdline[cmdlineBaseOffset - 1] == '/') {
155157
break;
@@ -309,17 +311,37 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
309311
char* strStart = mc->str;
310312
char* str = strStart;
311313

312-
int cmdlineBasenameStart = this->cmdlineBasenameStart;
313-
int cmdlineBasenameEnd = this->cmdlineBasenameEnd;
314+
size_t cmdlineBasenameStart = this->cmdlineBasenameStart;
315+
size_t cmdlineBasenameLen = 0;
316+
if (this->cmdlineBasenameEnd > this->cmdlineBasenameStart)
317+
cmdlineBasenameLen = this->cmdlineBasenameEnd - this->cmdlineBasenameStart;
314318

315319
if (!cmdline) {
316320
cmdlineBasenameStart = 0;
317-
cmdlineBasenameEnd = 0;
321+
cmdlineBasenameLen = 0;
318322
cmdline = "(zombie)";
319323
}
320324

321-
assert(cmdlineBasenameStart >= 0);
322-
assert(cmdlineBasenameStart <= (int)strlen(cmdline));
325+
assert(cmdlineBasenameStart <= strlen(cmdline));
326+
327+
size_t exeLen = 0;
328+
size_t exeBasenameOffset = 0;
329+
size_t exeBasenameLen = 0;
330+
size_t matchLen = 0;
331+
if (procExe) {
332+
exeLen = strlen(procExe);
333+
exeBasenameOffset = this->procExeBasenameOffset;
334+
exeBasenameLen = exeLen - exeBasenameOffset;
335+
336+
assert(exeBasenameOffset <= strlen(procExe));
337+
338+
if (this->cmdline) {
339+
matchLen = matchCmdlinePrefixWithExeSuffix(this->cmdline, &cmdlineBasenameStart, procExe, exeBasenameOffset, exeBasenameLen);
340+
}
341+
if (matchLen) {
342+
cmdlineBasenameLen = exeBasenameLen;
343+
}
344+
}
323345

324346
if (!showMergedCommand || !procExe || !procComm) { /* fall back to cmdline */
325347
if ((showMergedCommand || (Process_isUserlandThread(this) && showThreadNames)) && procComm && strlen(procComm)) { /* set column to or prefix it with comm */
@@ -337,37 +359,62 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
337359
if (shadowDistPathPrefix && showProgramPath)
338360
CHECK_AND_MARK_DIST_PATH_PREFIXES(cmdline);
339361

340-
if (cmdlineBasenameEnd > cmdlineBasenameStart)
341-
WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameEnd - cmdlineBasenameStart, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
362+
if (cmdlineBasenameLen > 0) {
363+
WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
342364

343-
if (this->procExeDeleted)
344-
WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameEnd - cmdlineBasenameStart, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
345-
else if (this->usesDeletedLib)
346-
WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameEnd - cmdlineBasenameStart, delLibAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
365+
if (this->procExeDeleted)
366+
WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
367+
else if (this->usesDeletedLib)
368+
WRITE_HIGHLIGHT(showProgramPath ? cmdlineBasenameStart : 0, cmdlineBasenameLen, delLibAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
369+
}
347370

348371
(void)stpcpyWithNewlineConversion(str, cmdline + (showProgramPath ? 0 : cmdlineBasenameStart));
349372

350373
return;
351374
}
352375

353-
int exeLen = strlen(this->procExe);
354-
int exeBasenameOffset = this->procExeBasenameOffset;
355-
int exeBasenameLen = exeLen - exeBasenameOffset;
356-
357-
assert(exeBasenameOffset >= 0);
358-
assert(exeBasenameOffset <= (int)strlen(procExe));
376+
size_t commLen = 0;
359377

360378
bool haveCommInExe = false;
361379
if (procExe && procComm && (!Process_isUserlandThread(this) || showThreadNames)) {
362380
haveCommInExe = strncmp(procExe + exeBasenameOffset, procComm, TASK_COMM_LEN - 1) == 0;
363381
}
382+
if (haveCommInExe) {
383+
commLen = exeBasenameLen;
384+
}
385+
386+
bool haveCommInCmdline = false;
387+
size_t commStart = 0;
388+
389+
if (!haveCommInExe && this->cmdline && procComm && searchCommInCmdline && (!Process_isUserlandThread(this) || showThreadNames)) {
390+
haveCommInCmdline = findCommInCmdline(procComm, cmdline, cmdlineBasenameStart, &commStart, &commLen);
391+
}
392+
393+
if (!stripExeFromCmdline) {
394+
matchLen = 0;
395+
}
396+
if (matchLen) {
397+
/* strip the matched exe prefix */
398+
cmdline += matchLen;
399+
400+
if (haveCommInCmdline) {
401+
if (commStart == cmdlineBasenameStart) {
402+
haveCommInExe = true;
403+
haveCommInCmdline = false;
404+
commStart = 0;
405+
} else {
406+
assert(commStart >= matchLen);
407+
commStart -= matchLen;
408+
}
409+
}
410+
}
364411

365412
/* Start with copying exe */
366413
if (showProgramPath) {
367414
if (shadowDistPathPrefix)
368415
CHECK_AND_MARK_DIST_PATH_PREFIXES(procExe);
369416
if (haveCommInExe)
370-
WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
417+
WRITE_HIGHLIGHT(exeBasenameOffset, commLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
371418
WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
372419
if (this->procExeDeleted)
373420
WRITE_HIGHLIGHT(exeBasenameOffset, exeBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
@@ -376,7 +423,7 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
376423
str = stpcpy(str, procExe);
377424
} else {
378425
if (haveCommInExe)
379-
WRITE_HIGHLIGHT(0, exeBasenameLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
426+
WRITE_HIGHLIGHT(0, commLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
380427
WRITE_HIGHLIGHT(0, exeBasenameLen, baseAttr, CMDLINE_HIGHLIGHT_FLAG_BASENAME);
381428
if (this->procExeDeleted)
382429
WRITE_HIGHLIGHT(0, exeBasenameLen, delExeAttr, CMDLINE_HIGHLIGHT_FLAG_DELETED);
@@ -385,18 +432,6 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
385432
str = stpcpy(str, procExe + exeBasenameOffset);
386433
}
387434

388-
bool haveCommInCmdline = false;
389-
int commStart = 0;
390-
int commEnd = 0;
391-
392-
/* Try to match procComm with procExe's basename: This is reliable (predictable) */
393-
if (searchCommInCmdline) {
394-
/* commStart/commEnd will be adjusted later along with cmdline */
395-
haveCommInCmdline = (!Process_isUserlandThread(this) || showThreadNames) && findCommInCmdline(procComm, cmdline, cmdlineBasenameStart, &commStart, &commEnd);
396-
}
397-
398-
int matchLen = matchCmdlinePrefixWithExeSuffix(cmdline, cmdlineBasenameStart, procExe, exeBasenameOffset, exeBasenameLen);
399-
400435
bool haveCommField = false;
401436

402437
if (!haveCommInExe && !haveCommInCmdline && procComm && (!Process_isUserlandThread(this) || showThreadNames)) {
@@ -406,18 +441,6 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
406441
haveCommField = true;
407442
}
408443

409-
if (matchLen) {
410-
if (stripExeFromCmdline) {
411-
/* strip the matched exe prefix */
412-
cmdline += matchLen;
413-
414-
commStart -= matchLen;
415-
commEnd -= matchLen;
416-
} else {
417-
matchLen = 0;
418-
}
419-
}
420-
421444
if (!matchLen || (haveCommField && *cmdline)) {
422445
/* cmdline will be a separate field */
423446
WRITE_SEPARATOR;
@@ -427,7 +450,7 @@ void Process_makeCommandStr(Process* this, const Settings* settings) {
427450
CHECK_AND_MARK_DIST_PATH_PREFIXES(cmdline);
428451

429452
if (!haveCommInExe && haveCommInCmdline && !haveCommField && (!Process_isUserlandThread(this) || showThreadNames))
430-
WRITE_HIGHLIGHT(commStart, commEnd - commStart, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
453+
WRITE_HIGHLIGHT(commStart, commLen, commAttr, CMDLINE_HIGHLIGHT_FLAG_COMM);
431454

432455
/* Display cmdline if it hasn't been consumed by procExe */
433456
if (*cmdline)
@@ -445,20 +468,20 @@ void Process_writeCommand(const Process* this, int attr, int baseAttr, RichStrin
445468
const ProcessMergedCommand* mc = &this->mergedCommand;
446469
const char* mergedCommand = mc->str;
447470

448-
int strStart = RichString_size(str);
471+
size_t strStart = RichString_size(str);
449472

450473
const Settings* settings = this->super.host->settings;
451474
const bool highlightBaseName = settings->highlightBaseName;
452475
const bool highlightSeparator = true;
453476
const bool highlightDeleted = settings->highlightDeletedExe;
454477

455478
if (!mergedCommand) {
456-
int len = 0;
479+
size_t len = 0;
457480
const char* cmdline = this->cmdline;
458481

459482
if (highlightBaseName || !settings->showProgramPath) {
460-
int basename = 0;
461-
for (int i = 0; i < this->cmdlineBasenameEnd; i++) {
483+
size_t basename = 0;
484+
for (size_t i = 0; i < this->cmdlineBasenameEnd; i++) {
462485
if (cmdline[i] == '/') {
463486
basename = i + 1;
464487
} else if (cmdline[i] == ':') {
@@ -849,7 +872,7 @@ bool Process_rowMatchesFilter(const Row* super, const Table* table) {
849872
void Process_init(Process* this, const Machine* host) {
850873
Row_init(&this->super, host);
851874

852-
this->cmdlineBasenameEnd = -1;
875+
this->cmdlineBasenameEnd = 0;
853876
this->st_uid = (uid_t)-1;
854877
}
855878

@@ -1001,12 +1024,12 @@ void Process_updateComm(Process* this, const char* comm) {
10011024
this->mergedCommand.lastUpdate = 0;
10021025
}
10031026

1004-
static int skipPotentialPath(const char* cmdline, int end) {
1027+
static size_t skipPotentialPath(const char* cmdline, size_t end) {
10051028
if (cmdline[0] != '/')
10061029
return 0;
10071030

1008-
int slash = 0;
1009-
for (int i = 1; i < end; i++) {
1031+
size_t slash = 0;
1032+
for (size_t i = 1; i < end; i++) {
10101033
if (cmdline[i] == '/' && cmdline[i + 1] != '\0') {
10111034
slash = i + 1;
10121035
continue;
@@ -1022,11 +1045,10 @@ static int skipPotentialPath(const char* cmdline, int end) {
10221045
return slash;
10231046
}
10241047

1025-
void Process_updateCmdline(Process* this, const char* cmdline, int basenameStart, int basenameEnd) {
1026-
assert(basenameStart >= 0);
1027-
assert((cmdline && basenameStart < (int)strlen(cmdline)) || (!cmdline && basenameStart == 0));
1048+
void Process_updateCmdline(Process* this, const char* cmdline, size_t basenameStart, size_t basenameEnd) {
1049+
assert((cmdline && basenameStart < strlen(cmdline)) || (!cmdline && basenameStart == 0));
10281050
assert((basenameEnd > basenameStart) || (basenameEnd == 0 && basenameStart == 0));
1029-
assert((cmdline && basenameEnd <= (int)strlen(cmdline)) || (!cmdline && basenameEnd == 0));
1051+
assert((cmdline && basenameEnd <= strlen(cmdline)) || (!cmdline && basenameEnd == 0));
10301052

10311053
if (!this->cmdline && !cmdline)
10321054
return;
@@ -1059,7 +1081,7 @@ void Process_updateExe(Process* this, const char* exe) {
10591081
if (exe) {
10601082
this->procExe = xStrdup(exe);
10611083
const char* lastSlash = strrchr(exe, '/');
1062-
this->procExeBasenameOffset = (lastSlash && *(lastSlash + 1) != '\0' && lastSlash != exe) ? (lastSlash - exe + 1) : 0;
1084+
this->procExeBasenameOffset = (lastSlash && *(lastSlash + 1) != '\0' && lastSlash != exe) ? (size_t)(lastSlash - exe + 1) : 0;
10631085
} else {
10641086
this->procExe = NULL;
10651087
this->procExeBasenameOffset = 0;

Process.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@ typedef struct Process_ {
129129
char* cmdline;
130130

131131
/* End Offset in cmdline of the process basename */
132-
int cmdlineBasenameEnd;
132+
size_t cmdlineBasenameEnd;
133133

134134
/* Start Offset in cmdline of the process basename */
135-
int cmdlineBasenameStart;
135+
size_t cmdlineBasenameStart;
136136

137137
/* The process' "command" name */
138138
char* procComm;
@@ -144,7 +144,7 @@ typedef struct Process_ {
144144
char* procCwd;
145145

146146
/* Offset in procExe of the process basename */
147-
int procExeBasenameOffset;
147+
size_t procExeBasenameOffset;
148148

149149
/* Tells if the executable has been replaced in the filesystem since start */
150150
bool procExeDeleted;
@@ -326,7 +326,7 @@ int Process_compareByKey_Base(const Process* p1, const Process* p2, ProcessField
326326
const char* Process_getCommand(const Process* this);
327327

328328
void Process_updateComm(Process* this, const char* comm);
329-
void Process_updateCmdline(Process* this, const char* cmdline, int basenameStart, int basenameEnd);
329+
void Process_updateCmdline(Process* this, const char* cmdline, size_t basenameStart, size_t basenameEnd);
330330
void Process_updateExe(Process* this, const char* exe);
331331

332332
/* This function constructs the string that is displayed by

0 commit comments

Comments
 (0)