aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2020-03-26 02:15:59 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2020-03-26 02:15:59 -0400
commit37ec63ece45c7f27f576e1fb5911b55630125d03 (patch)
tree843d82c165c784997bedf2ad36f078f932b1643d
parentd0925dcc2e34d6f9a8c554ca97c4d75784e6f69d (diff)
downloadspmc-37ec63ece45c7f27f576e1fb5911b55630125d03.tar.gz
Fix segfault caused by freeing records for no reason:
* split() returns the input string when no delimiters are found
-rw-r--r--lib/config.c9
-rw-r--r--lib/manifest.c12
-rw-r--r--lib/resolve.c3
-rw-r--r--lib/str.c11
-rw-r--r--lib/version_spec.c5
5 files changed, 22 insertions, 18 deletions
diff --git a/lib/config.c b/lib/config.c
index 88c96fd..292c633 100644
--- a/lib/config.c
+++ b/lib/config.c
@@ -22,7 +22,8 @@
* @return success=`ConfigItem` array, failure=NULL
*/
ConfigItem **config_read(const char *filename) {
- const char sep = '=';
+ const char sep_ch = '=';
+ const char sep_str[] = {sep_ch, '\0'};
size_t record = 0;
char *line = NULL;
FILE *fp = NULL;
@@ -71,16 +72,16 @@ ConfigItem **config_read(const char *filename) {
}
// Get a pointer to the key pair separator
- char *sep_pos = strchr(lptr, sep);
+ char *sep_pos = strchr(lptr, sep_ch);
if (!sep_pos) {
- printf("invalid entry on line %zu: missing '%c': '%s'\n", record, sep, lptr);
+ printf("invalid entry on line %zu: missing '%s': '%s'\n", record, sep_str, lptr);
continue;
}
// These values are approximations. The real length(s) are recorded using strlen below.
// At most we'll lose a few heap bytes to whitespace, but it's better than allocating PATH_MAX or BUFSIZ
// for a measly ten byte string.
- size_t key_length = strcspn(lptr, &sep);
+ size_t key_length = strcspn(lptr, sep_str);
size_t value_length = strlen(sep_pos);
// Allocate a ConfigItem record
diff --git a/lib/manifest.c b/lib/manifest.c
index 08aafbf..2d306e7 100644
--- a/lib/manifest.c
+++ b/lib/manifest.c
@@ -474,9 +474,10 @@ Manifest *manifest_read(char *file_or_url) {
info->records = total_records;
while (fgets(dptr, BUFSIZ, fp) != NULL) {
dptr = strip(dptr);
- char *garbage;
+ char *garbage = NULL;
char **parts = split(dptr, separator);
char *_origin = NULL;
+
if (file_or_url != NULL) {
_origin = strdup(file_or_url);
}
@@ -499,7 +500,6 @@ Manifest *manifest_read(char *file_or_url) {
info->packages[i]->requirements = NULL;
if (strncmp(parts[6], SPM_MANIFEST_NODATA, strlen(SPM_MANIFEST_NODATA)) != 0) {
info->packages[i]->requirements = split(parts[6], ",");
-
}
if (strncmp(parts[7], SPM_MANIFEST_NODATA, strlen(SPM_MANIFEST_NODATA)) != 0) {
memset(info->packages[i]->checksum_sha256, '\0', SHA256_DIGEST_STRING_LENGTH);
@@ -527,14 +527,14 @@ Manifest *manifest_read(char *file_or_url) {
*/
ManifestPackage *manifest_search(const Manifest *info, const char *_package) {
ManifestPackage *match = NULL;
- char package[PATH_MAX];
-
- memset(package, '\0', PATH_MAX);
- strncpy(package, _package, PATH_MAX);
+ char *package = strdup(_package);
if ((match = find_by_strspec(info, package)) != NULL) {
+ free(package);
return match;
}
+
+ free(package);
return NULL;
}
diff --git a/lib/resolve.c b/lib/resolve.c
index 1a4448f..5065ae9 100644
--- a/lib/resolve.c
+++ b/lib/resolve.c
@@ -38,7 +38,7 @@ ManifestPackage **resolve_dependencies(ManifestList *manifests, const char *spec
ManifestPackage *package = manifestlist_search(manifests, spec);
ManifestPackage *requirement = NULL;
- if (package == NULL) {
+ if (package == NULL || package->requirements == NULL) {
return requirements;
}
@@ -48,6 +48,7 @@ ManifestPackage **resolve_dependencies(ManifestList *manifests, const char *spec
fprintf(stderr, "ERROR: unable to resolve package via manifestlist_search(): '%s'\n", package->requirements[i]);
exit(1);
}
+
if (resolve_has_dependency(requirement->archive)) {
free(requirement);
} else {
diff --git a/lib/str.c b/lib/str.c
index 3736e2f..0e2f90e 100644
--- a/lib/str.c
+++ b/lib/str.c
@@ -196,11 +196,6 @@ char** split(char *_sptr, const char* delim)
split_alloc += num_chars(sptr, delim[i]);
}
- if (split_alloc == 0) {
- free(orig);
- return NULL;
- }
-
// Preallocate enough records based on the number of delimiters
char **result = (char **)calloc(split_alloc + 2, sizeof(char *));
if (!result) {
@@ -208,6 +203,12 @@ char** split(char *_sptr, const char* delim)
return NULL;
}
+ // No delimiter, but the string was not NULL, so return the original string
+ if (split_alloc == 0) {
+ result[0] = sptr;
+ return result;
+ }
+
// Separate the string into individual parts and store them in the result array
int i = 0;
char *token = NULL;
diff --git a/lib/version_spec.c b/lib/version_spec.c
index d7c8b2e..baf0f71 100644
--- a/lib/version_spec.c
+++ b/lib/version_spec.c
@@ -408,7 +408,6 @@ ManifestPackage *find_by_strspec(const Manifest *manifest, const char *_strspec)
get_name(&name, strspec);
pos = get_operators(&op, strspec);
-
ManifestPackage **m = NULL;
// No operators found
if (pos == NULL) {
@@ -430,13 +429,15 @@ ManifestPackage *find_by_strspec(const Manifest *manifest, const char *_strspec)
selected = m[i];
}
+ /* TODO: What on earth was I trying to do here? Why am I freeing the manifest (pointers)
ManifestPackage *result = manifest_package_copy(selected);
for (size_t i = 0; m[i] != NULL; i++) {
manifest_package_free(m[i]);
}
free(m);
+ */
free(strspec);
- return result;
+ return selected;
}
// Obviously it didn't work out