-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternatives: Fix issues found by static analyzers #126
Merged
Merged
Changes from 6 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
e47405e
alternatives: fix memory leak
lnykryn 5140aa7
alternatives: initialize parameters in main to NULL
lnykryn caaa4d6
alternatives: fix memory leak
lnykryn c296618
alternatives: fix memory leak
lnykryn ec56116
alternatives: fix leak
lnykryn e8dd7ab
alternatives: fix all the leaks of read line in readConfig
lnykryn 44ba44f
alternatives: fix all the leaks of groups in readConfig
lnykryn c247ff1
alternatives: fix possible overrun
lnykryn d71bac5
alternatives: fix leak
lnykryn 0268377
alternatives: fix leak
lnykryn 5e2658d
alternatives: use exit in main instead of return for critical failures
lnykryn e406ed8
alternatives: properly handle chars with const in normalize_path
lnykryn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,7 +106,7 @@ static int usage(int rc) { | |
exit(rc); | ||
} | ||
|
||
/* | ||
/* | ||
* Function to clean path form unnecessary backslashes | ||
* It will make from //abcd///efgh/ -> /abcd/efgh/ | ||
*/ | ||
|
@@ -120,7 +120,7 @@ const char *normalize_path(const char *s) { | |
} while (*dst == '/' && *src == '/'); | ||
dst++; | ||
} | ||
} | ||
} | ||
return (const char *)s; | ||
} | ||
|
||
|
@@ -134,6 +134,12 @@ int streq(const char *a, const char *b) { | |
return 0; | ||
} | ||
|
||
char * strsteal(char **ptr) { | ||
char *ret = *ptr; | ||
*ptr = NULL; | ||
return ret; | ||
} | ||
|
||
int altBetter(struct alternative new, struct alternative old, char *family) { | ||
if (!family || (streq(old.family, family) == streq(new.family, family))) | ||
return new.priority > old.priority; | ||
|
@@ -261,6 +267,11 @@ char *parseLine(char **buf) { | |
return strdup(start); | ||
} | ||
|
||
void nextLine(char **buf, char **line) { | ||
free(*line); | ||
*line = parseLine(buf); | ||
} | ||
|
||
static int readConfig(struct alternativeSet *set, const char *title, | ||
const char *altDir, const char *stateDir, int flags) { | ||
char *path; | ||
|
@@ -270,13 +281,15 @@ static int readConfig(struct alternativeSet *set, const char *title, | |
struct stat sb; | ||
char *buf; | ||
char *end; | ||
char *line; | ||
char *line = NULL; | ||
char *ptr; | ||
struct { | ||
char *facility; | ||
char *title; | ||
} *groups = NULL; | ||
int numGroups = 0; | ||
char linkBuf[PATH_MAX]; | ||
int r = 0; | ||
|
||
set->alts = NULL; | ||
set->numAlts = 0; | ||
|
@@ -309,10 +322,11 @@ static int readConfig(struct alternativeSet *set, const char *title, | |
close(fd); | ||
buf[sb.st_size] = '\0'; | ||
|
||
line = parseLine(&buf); | ||
nextLine(&buf, &line); | ||
if (!line) { | ||
fprintf(stderr, _("%s empty!\n"), path); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
|
||
if (!strcmp(line, "auto")) { | ||
|
@@ -321,93 +335,102 @@ static int readConfig(struct alternativeSet *set, const char *title, | |
set->mode = MANUAL; | ||
} else { | ||
fprintf(stderr, _("bad mode on line 1 of %s\n"), path); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
free(line); | ||
|
||
line = parseLine(&buf); | ||
nextLine(&buf, &line); | ||
if (!line || *line != '/') { | ||
fprintf(stderr, _("bad primary link in %s\n"), path); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
|
||
groups = realloc(groups, sizeof(*groups)); | ||
groups[0].title = strdup(title); | ||
groups[0].facility = line; | ||
groups[0].facility = strsteal(&line); | ||
numGroups = 1; | ||
|
||
line = parseLine(&buf); | ||
nextLine(&buf, &line); | ||
while (line && *line) { | ||
if (*line == '/') { | ||
fprintf(stderr, _("path %s unexpected in %s\n"), line, path); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
|
||
groups = realloc(groups, sizeof(*groups) * (numGroups + 1)); | ||
groups[numGroups].title = line; | ||
groups[numGroups].title = strsteal(&line); | ||
|
||
line = parseLine(&buf); | ||
nextLine(&buf, &line); | ||
if (!line || !*line) { | ||
fprintf(stderr, _("missing path for follower %s in %s\n"), line, path); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
|
||
groups[numGroups++].facility = line; | ||
groups[numGroups++].facility = strsteal(&line); | ||
|
||
line = parseLine(&buf); | ||
nextLine(&buf, &line); | ||
} | ||
|
||
if (!line) { | ||
fprintf(stderr, _("unexpected end of file in %s\n"), path); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
|
||
line = parseLine(&buf); | ||
nextLine(&buf, &line); | ||
while (line && *line) { | ||
set->alts = realloc(set->alts, (set->numAlts + 1) * sizeof(*set->alts)); | ||
|
||
if (*line != '/') { | ||
fprintf(stderr, _("path to alternate expected in %s\n"), path); | ||
fprintf(stderr, _("unexpected line in %s: %s\n"), path, line); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
|
||
set->alts[set->numAlts].leader.facility = strdup(normalize_path(groups[0].facility)); | ||
set->alts[set->numAlts].leader.title = strdup(groups[0].title); | ||
set->alts[set->numAlts].leader.target = line; | ||
set->alts[set->numAlts].leader.target = strsteal(&line); | ||
set->alts[set->numAlts].numFollowers = numGroups - 1; | ||
if (numGroups > 1) | ||
set->alts[set->numAlts].followers = malloc( | ||
(numGroups - 1) * sizeof(*set->alts[set->numAlts].followers)); | ||
else | ||
set->alts[set->numAlts].followers = NULL; | ||
|
||
line = parseLine(&buf); | ||
set->alts[set->numAlts].priority = -1; | ||
set->alts[set->numAlts].initscript = NULL; | ||
set->alts[set->numAlts].family = NULL; | ||
|
||
if (line && line[0] == '@') { | ||
line++; | ||
end = strchr(line, '@'); | ||
if (!end || (end == line)) { | ||
nextLine(&buf, &line); | ||
ptr = line; | ||
|
||
if (ptr && ptr[0] == '@') { | ||
ptr++; | ||
end = strchr(ptr, '@'); | ||
if (!end || (end == ptr)) { | ||
fprintf(stderr, | ||
_("closing '@' missing or the family is empty in %s\n"), | ||
path); | ||
fprintf(stderr, _("unexpected line in %s: %s\n"), path, line); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
*end = '\0'; | ||
set->alts[set->numAlts].family = strdup(line); | ||
line = end + 1; | ||
set->alts[set->numAlts].family = strdup(ptr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto. |
||
ptr = end + 1; | ||
} | ||
|
||
set->alts[set->numAlts].priority = strtol(line, &end, 0); | ||
set->alts[set->numAlts].priority = strtol(ptr, &end, 0); | ||
|
||
if (!end || (end == line)) { | ||
if (!end || (end == ptr)) { | ||
fprintf(stderr, _("numeric priority expected in %s\n"), path); | ||
fprintf(stderr, _("unexpected line in %s: %s\n"), path, line); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
if (end) { | ||
while (*end && isspace(*end)) | ||
|
@@ -421,31 +444,33 @@ static int readConfig(struct alternativeSet *set, const char *title, | |
set->best = set->numAlts; | ||
|
||
for (i = 1; i < numGroups; i++) { | ||
line = parseLine(&buf); | ||
nextLine(&buf, &line); | ||
if (line && strlen(line) && *line != '/') { | ||
fprintf(stderr, _("follower path expected in %s\n"), path); | ||
fprintf(stderr, _("unexpected line in %s: %s\n"), path, line); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
|
||
set->alts[set->numAlts].followers[i - 1].title = | ||
strdup(groups[i].title); | ||
set->alts[set->numAlts].followers[i - 1].facility = | ||
strdup(normalize_path(groups[i].facility)); | ||
set->alts[set->numAlts].followers[i - 1].target = | ||
(line && strlen(line)) ? line : NULL; | ||
(line && strlen(line)) ? strsteal(&line) : NULL; | ||
} | ||
|
||
set->numAlts++; | ||
|
||
line = parseLine(&buf); | ||
nextLine(&buf, &line); | ||
} | ||
|
||
while (line) { | ||
line = parseLine(&buf); | ||
nextLine(&buf, &line); | ||
if (line && *line) { | ||
fprintf(stderr, _("unexpected line in %s: %s\n"), path, line); | ||
return 1; | ||
r = 1; | ||
goto finish; | ||
} | ||
} | ||
|
||
|
@@ -480,8 +505,9 @@ static int readConfig(struct alternativeSet *set, const char *title, | |
} | ||
|
||
set->currentLink = strdup(normalize_path(linkBuf)); | ||
|
||
return 0; | ||
finish: | ||
free(line); | ||
return r; | ||
} | ||
|
||
static int isLink(char *path) { | ||
|
@@ -1253,7 +1279,9 @@ static int listServices(const char *altDir, const char *stateDir, int flags) { | |
int main(int argc, const char **argv) { | ||
const char **nextArg; | ||
char *end; | ||
char *title, *target, *followerTitle; | ||
char *title = NULL; | ||
char *target = NULL; | ||
char *followerTitle = NULL; | ||
enum programModes mode = MODE_UNKNOWN; | ||
struct alternative newAlt = {-1, {NULL, NULL, NULL}, NULL, NULL, 0, NULL}; | ||
int flags = 0; | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can still leak if
goto finish
happens beforenumGroups
is incremented.