Skip to content
Snippets Groups Projects
Commit ceb0fd0f authored by deuce's avatar deuce
Browse files

Fix memory leak in wordwrap() where the paragraph array was never free()d.

Add a great deal of comments for future-Deuce.
parent 5710fda8
No related branches found
No related tags found
No related merge requests found
...@@ -51,6 +51,11 @@ enum prefix_pos { ...@@ -51,6 +51,11 @@ enum prefix_pos {
PREFIX_FINISHED PREFIX_FINISHED
}; };
/*
* Parses a prefix from the passed text, returns a struct containing
* an allocated bytes pointer and the number of columns the prefix
* takes up in the output.
*/
static struct prefix parse_prefix(const char *text) static struct prefix parse_prefix(const char *text)
{ {
enum prefix_pos expect = PREFIX_START; enum prefix_pos expect = PREFIX_START;
...@@ -132,6 +137,9 @@ static struct prefix parse_prefix(const char *text) ...@@ -132,6 +137,9 @@ static struct prefix parse_prefix(const char *text)
return ret; return ret;
} }
/*
* Appends to a malloc()ed buffer, realloc()ing if needed.
*/
static void outbuf_append(char **outbuf, char **outp, char *append, int len, int *outlen) static void outbuf_append(char **outbuf, char **outp, char *append, int len, int *outlen)
{ {
char *p; char *p;
...@@ -160,11 +168,21 @@ static void outbuf_append(char **outbuf, char **outp, char *append, int len, int ...@@ -160,11 +168,21 @@ static void outbuf_append(char **outbuf, char **outp, char *append, int len, int
return; return;
} }
/*
* Holds the length of a "section"... either a word or whitespace.
* Length is in bytes and "len" (the number of columns)
*/
struct section_len { struct section_len {
int bytes; int bytes;
int len; int len;
}; };
/*
* Gets the length of a run of whitespace starting at the beginning
* of buf, which occurs in column col.
*
* The column is needed for tab size calculations.
*/
static struct section_len get_ws_len(char *buf, int col) static struct section_len get_ws_len(char *buf, int col)
{ {
struct section_len ret = {0,0}; struct section_len ret = {0,0};
...@@ -186,6 +204,15 @@ static struct section_len get_ws_len(char *buf, int col) ...@@ -186,6 +204,15 @@ static struct section_len get_ws_len(char *buf, int col)
return ret; return ret;
} }
/*
* Gets the length of a word, optionally limiting the max number
* of columns to consume to maxlen.
*
* When maxlen < 0, returns the word length in cols and bytes.
* When maxlen >= 0, returns the number of cols and bytes up to
* maxlen cols (used to find the number of bytes to fill a specific
* number of columns).
*/
static struct section_len get_word_len(char *buf, int maxlen) static struct section_len get_word_len(char *buf, int maxlen)
{ {
struct section_len ret = {0,0}; struct section_len ret = {0,0};
...@@ -216,15 +243,21 @@ static struct section_len get_word_len(char *buf, int maxlen) ...@@ -216,15 +243,21 @@ static struct section_len get_word_len(char *buf, int maxlen)
} }
/* /*
* This unwraps a message into infinite line length with separate prefix. * This structure holds a "paragraph" defined as everything from either
* the beginning of the message, or the previous hard CR to the next
* hard CR or end of message
*/ */
struct paragraph { struct paragraph {
struct prefix prefix; struct prefix prefix;
char *text; char *text;
size_t alloc_size; size_t alloc_size;
}; };
/*
* Free()s the allocations in an array of paragraphs. If count is
* provided, that many paragraphs are freed. If count == -1, frees
* up to the first paragraph with a NULL text member.
*/
static void free_paragraphs(struct paragraph *paragraph, int count) static void free_paragraphs(struct paragraph *paragraph, int count)
{ {
int i; int i;
...@@ -237,6 +270,9 @@ static void free_paragraphs(struct paragraph *paragraph, int count) ...@@ -237,6 +270,9 @@ static void free_paragraphs(struct paragraph *paragraph, int count)
} }
} }
/*
* Appends bytes to a paragraph, realloc()ing space if needed.
*/
static BOOL paragraph_append(struct paragraph *paragraph, const char *bytes, size_t count) static BOOL paragraph_append(struct paragraph *paragraph, const char *bytes, size_t count)
{ {
size_t len = strlen(paragraph->text); size_t len = strlen(paragraph->text);
...@@ -254,6 +290,13 @@ static BOOL paragraph_append(struct paragraph *paragraph, const char *bytes, siz ...@@ -254,6 +290,13 @@ static BOOL paragraph_append(struct paragraph *paragraph, const char *bytes, siz
return TRUE; return TRUE;
} }
/*
* This unwraps a message into infinite line length paragraphs.
* Optionally, each with separate prefix.
*
* The returned malloc()ed array will have the text member of the last
* paragraph set to NULL.
*/
static struct paragraph *word_unwrap(char *inbuf, int oldlen, BOOL handle_quotes) static struct paragraph *word_unwrap(char *inbuf, int oldlen, BOOL handle_quotes)
{ {
unsigned inpos=0; unsigned inpos=0;
...@@ -387,6 +430,12 @@ fail_return: ...@@ -387,6 +430,12 @@ fail_return:
return NULL; return NULL;
} }
/*
* Wraps a set of infinite line length paragraphs to the specified length
* optionally prepending the prefixes.
*
* Returns a malloc()ed string.
*/
static char *wrap_paragraphs(struct paragraph *paragraph, int outlen, BOOL handle_quotes) static char *wrap_paragraphs(struct paragraph *paragraph, int outlen, BOOL handle_quotes)
{ {
int outcol; int outcol;
...@@ -465,5 +514,6 @@ char* wordwrap(char* inbuf, int len, int oldlen, BOOL handle_quotes) ...@@ -465,5 +514,6 @@ char* wordwrap(char* inbuf, int len, int oldlen, BOOL handle_quotes)
paragraphs = word_unwrap(inbuf, oldlen, handle_quotes); paragraphs = word_unwrap(inbuf, oldlen, handle_quotes);
outbuf = wrap_paragraphs(paragraphs, oldlen, handle_quotes); outbuf = wrap_paragraphs(paragraphs, oldlen, handle_quotes);
free_paragraphs(paragraphs, -1); free_paragraphs(paragraphs, -1);
free(paragraphs);
return outbuf; return outbuf;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment