diff options
Diffstat (limited to 'package/opkg/patches/020-avoid_getline.patch')
-rw-r--r-- | package/opkg/patches/020-avoid_getline.patch | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/package/opkg/patches/020-avoid_getline.patch b/package/opkg/patches/020-avoid_getline.patch new file mode 100644 index 0000000..8a1a8f6 --- /dev/null +++ b/package/opkg/patches/020-avoid_getline.patch @@ -0,0 +1,317 @@ +--- a/libopkg/parse_util.c ++++ b/libopkg/parse_util.c +@@ -22,6 +22,7 @@ + #include "libbb/libbb.h" + + #include "parse_util.h" ++#include "pkg_parse.h" + + int + is_field(const char *type, const char *line) +@@ -86,3 +87,84 @@ parse_list(const char *raw, unsigned int + *count = line_count; + return depends; + } ++ ++int ++parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask, ++ char **buf0, size_t buf0len) ++{ ++ int ret, lineno; ++ char *buf, *nl; ++ size_t buflen; ++ ++ lineno = 1; ++ ret = 0; ++ ++ buflen = buf0len; ++ buf = *buf0; ++ buf[0] = '\0'; ++ ++ while (1) { ++ if (fgets(buf, (int)buflen, fp) == NULL) { ++ if (ferror(fp)) { ++ opkg_perror(ERROR, "fgets"); ++ ret = -1; ++ } else if (strlen(*buf0) == buf0len-1) { ++ opkg_msg(ERROR, "Missing new line character" ++ " at end of file!\n"); ++ parse_line(item, *buf0, mask); ++ } ++ break; ++ } ++ ++ nl = strchr(buf, '\n'); ++ if (nl == NULL) { ++ if (strlen(buf) < buflen-1) { ++ /* ++ * Line could be exactly buflen-1 long and ++ * missing a newline, but we won't know until ++ * fgets fails to read more data. ++ */ ++ opkg_msg(ERROR, "Missing new line character" ++ " at end of file!\n"); ++ parse_line(item, *buf0, mask); ++ break; ++ } ++ if (buf0len >= EXCESSIVE_LINE_LEN) { ++ opkg_msg(ERROR, "Excessively long line at " ++ "%d. Corrupt file?\n", ++ lineno); ++ ret = -1; ++ break; ++ } ++ ++ /* ++ * Realloc and point buf past the data already read, ++ * at the NULL terminator inserted by fgets. ++ * |<--------------- buf0len ----------------->| ++ * | |<------- buflen ---->| ++ * |---------------------|---------------------| ++ * buf0 buf ++ */ ++ buflen = buf0len +1; ++ buf0len *= 2; ++ *buf0 = xrealloc(*buf0, buf0len); ++ buf = *buf0 + buflen -2; ++ ++ continue; ++ } ++ ++ *nl = '\0'; ++ ++ lineno++; ++ ++ if (parse_line(item, *buf0, mask)) ++ break; ++ ++ buf = *buf0; ++ buflen = buf0len; ++ buf[0] = '\0'; ++ } ++ ++ return ret; ++} ++ +--- a/libopkg/parse_util.h ++++ b/libopkg/parse_util.h +@@ -22,4 +22,8 @@ int is_field(const char *type, const cha + char *parse_simple(const char *type, const char *line); + char **parse_list(const char *raw, unsigned int *count, const char sep, int skip_field); + ++typedef int (*parse_line_t)(void *, const char *, uint); ++int parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask, ++ char **buf0, size_t buf0len); ++ + #endif +--- a/libopkg/pkg_hash.c ++++ b/libopkg/pkg_hash.c +@@ -23,6 +23,7 @@ + #include "opkg_message.h" + #include "pkg_vec.h" + #include "pkg_hash.h" ++#include "parse_util.h" + #include "pkg_parse.h" + #include "opkg_utils.h" + #include "sprintf_alloc.h" +@@ -119,8 +120,14 @@ pkg_hash_add_from_file(const char *file_ + pkg->src = src; + pkg->dest = dest; + +- ret = pkg_parse_from_stream_nomalloc(pkg, fp, 0, ++ ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, 0, + &buf, len); ++ ++ if (pkg->name == NULL) { ++ /* probably just a blank line */ ++ ret = 1; ++ } ++ + if (ret) { + pkg_deinit (pkg); + free(pkg); +--- a/libopkg/pkg_parse.c ++++ b/libopkg/pkg_parse.c +@@ -104,9 +104,11 @@ get_arch_priority(const char *arch) + return 0; + } + +-static int +-pkg_parse_line(pkg_t *pkg, const char *line, uint mask) ++int ++pkg_parse_line(void *ptr, const char *line, uint mask) + { ++ pkg_t *pkg = (pkg_t *) ptr; ++ + /* these flags are a bit hackish... */ + static int reading_conffiles = 0, reading_description = 0; + int ret = 0; +@@ -266,91 +268,6 @@ dont_reset_flags: + } + + int +-pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask, +- char **buf0, size_t buf0len) +-{ +- int ret, lineno; +- char *buf, *nl; +- size_t buflen; +- +- lineno = 1; +- ret = 0; +- +- buflen = buf0len; +- buf = *buf0; +- buf[0] = '\0'; +- +- while (1) { +- if (fgets(buf, (int)buflen, fp) == NULL) { +- if (ferror(fp)) { +- opkg_perror(ERROR, "fgets"); +- ret = -1; +- } else if (strlen(*buf0) == buf0len-1) { +- opkg_msg(ERROR, "Missing new line character" +- " at end of file!\n"); +- pkg_parse_line(pkg, *buf0, mask); +- } +- break; +- } +- +- nl = strchr(buf, '\n'); +- if (nl == NULL) { +- if (strlen(buf) < buflen-1) { +- /* +- * Line could be exactly buflen-1 long and +- * missing a newline, but we won't know until +- * fgets fails to read more data. +- */ +- opkg_msg(ERROR, "Missing new line character" +- " at end of file!\n"); +- pkg_parse_line(pkg, *buf0, mask); +- break; +- } +- if (buf0len >= EXCESSIVE_LINE_LEN) { +- opkg_msg(ERROR, "Excessively long line at " +- "%d. Corrupt file?\n", +- lineno); +- ret = -1; +- break; +- } +- +- /* +- * Realloc and point buf past the data already read, +- * at the NULL terminator inserted by fgets. +- * |<--------------- buf0len ----------------->| +- * | |<------- buflen ---->| +- * |---------------------|---------------------| +- * buf0 buf +- */ +- buflen = buf0len +1; +- buf0len *= 2; +- *buf0 = xrealloc(*buf0, buf0len); +- buf = *buf0 + buflen -2; +- +- continue; +- } +- +- *nl = '\0'; +- +- lineno++; +- +- if (pkg_parse_line(pkg, *buf0, mask)) +- break; +- +- buf = *buf0; +- buflen = buf0len; +- buf[0] = '\0'; +- } +- +- if (pkg->name == NULL) { +- /* probably just a blank line */ +- ret = 1; +- } +- +- return ret; +-} +- +-int + pkg_parse_from_stream(pkg_t *pkg, FILE *fp, uint mask) + { + int ret; +@@ -358,8 +275,13 @@ pkg_parse_from_stream(pkg_t *pkg, FILE * + const size_t len = 4096; + + buf = xmalloc(len); +- ret = pkg_parse_from_stream_nomalloc(pkg, fp, mask, &buf, len); ++ ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, mask, &buf, len); + free(buf); + ++ if (pkg->name == NULL) { ++ /* probably just a blank line */ ++ ret = 1; ++ } ++ + return ret; + } +--- a/libopkg/pkg_parse.h ++++ b/libopkg/pkg_parse.h +@@ -18,10 +18,11 @@ + #ifndef PKG_PARSE_H + #define PKG_PARSE_H + ++#include "pkg.h" ++ + int parse_version(pkg_t *pkg, const char *raw); + int pkg_parse_from_stream(pkg_t *pkg, FILE *fp, uint mask); +-int pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask, +- char **buf0, size_t buf0len); ++int pkg_parse_line(void *ptr, const char *line, uint mask); + + #define EXCESSIVE_LINE_LEN (4096 << 8) + +--- a/libopkg/release_parse.c ++++ b/libopkg/release_parse.c +@@ -23,8 +23,10 @@ + #include "parse_util.h" + + static int +-release_parse_line(release_t *release, const char *line) ++release_parse_line(void *ptr, const char *line, uint mask) + { ++ release_t *release = (release_t *) ptr; ++ + int ret = 0; + unsigned int count = 0; + char **list = 0; +@@ -111,25 +113,14 @@ dont_reset_flags: + int + release_parse_from_stream(release_t *release, FILE *fp) + { +- int ret = 0; +- char *buf = NULL; +- size_t buflen, nread; +- +- nread = getline(&buf, &buflen, fp); +- while ( nread != -1 ) { +- if (buf[nread-1] == '\n') buf[nread-1] = '\0'; +- if (release_parse_line(release, buf)) +- opkg_msg(DEBUG, "Failed to parse release line for %s:\n\t%s\n", +- release->name, buf); +- nread = getline(&buf, &buflen, fp); +- } +- +- if (!feof(fp)) { +- opkg_perror(ERROR, "Problems reading Release file for %sd\n", release->name); +- ret = -1; +- } ++ int ret; ++ char *buf; ++ const size_t len = 4096; + ++ buf = xmalloc(len); ++ ret = parse_from_stream_nomalloc(release_parse_line, release, fp, 0, &buf, len); + free(buf); ++ + return ret; + } + |