diff options
Diffstat (limited to 'libopkg')
-rw-r--r-- | libopkg/parse_util.c | 81 | ||||
-rw-r--r-- | libopkg/parse_util.h | 5 | ||||
-rw-r--r-- | libopkg/pkg_hash.c | 7 | ||||
-rw-r--r-- | libopkg/pkg_parse.c | 93 | ||||
-rw-r--r-- | libopkg/pkg_parse.h | 3 |
5 files changed, 99 insertions, 90 deletions
diff --git a/libopkg/parse_util.c b/libopkg/parse_util.c index e01b124..538bb11 100644 --- 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,83 @@ parse_list(const char *raw, unsigned int *count, const char sep, int skip_field) *count = line_count; return depends; } + +int +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'; + } + + return ret; +} diff --git a/libopkg/parse_util.h b/libopkg/parse_util.h index e4e2abe..d1aba4c 100644 --- a/libopkg/parse_util.h +++ b/libopkg/parse_util.h @@ -18,8 +18,13 @@ #ifndef PARSE_UTIL_H #define PARSE_UTIL_H +#include "pkg.h" + int is_field(const char *type, const char *line); char *parse_simple(const char *type, const char *line); char **parse_list(const char *raw, unsigned int *count, const char sep, int skip_field); +int parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask, + char **buf0, size_t buf0len); + #endif diff --git a/libopkg/pkg_hash.c b/libopkg/pkg_hash.c index 2a76be8..3e4d9d4 100644 --- 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,12 @@ pkg_hash_add_from_file(const char *file_name, pkg->src = src; pkg->dest = dest; - ret = pkg_parse_from_stream_nomalloc(pkg, fp, 0, + ret = parse_from_stream_nomalloc(pkg, fp, 0, &buf, len); + if (pkg->name == NULL) { + /* probably just a blank line */ + ret = 1; + } if (ret) { pkg_deinit (pkg); free(pkg); diff --git a/libopkg/pkg_parse.c b/libopkg/pkg_parse.c index e0d7fce..3f188a8 100644 --- a/libopkg/pkg_parse.c +++ b/libopkg/pkg_parse.c @@ -104,7 +104,7 @@ get_arch_priority(const char *arch) return 0; } -static int +int pkg_parse_line(pkg_t *pkg, const char *line, uint mask) { /* these flags are a bit hackish... */ @@ -266,91 +266,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,7 +273,11 @@ pkg_parse_from_stream(pkg_t *pkg, FILE *fp, uint mask) 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, fp, mask, &buf, len); + if (pkg->name == NULL) { + /* probably just a blank line */ + ret = 1; + } free(buf); return ret; diff --git a/libopkg/pkg_parse.h b/libopkg/pkg_parse.h index 7020a90..f477375 100644 --- a/libopkg/pkg_parse.h +++ b/libopkg/pkg_parse.h @@ -20,8 +20,7 @@ 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(pkg_t *pkg, const char *line, uint mask); #define EXCESSIVE_LINE_LEN (4096 << 8) |