From e7a4df6180f0234908f8bb56c958258ce1b499b2 Mon Sep 17 00:00:00 2001 From: "tg(x)" <*@tg-x.net> Date: Wed, 4 May 2011 17:46:20 +0200 Subject: [PATCH] fix for 0 length content/modifiers --- src/packet.c | 21 +++++++++++++-------- src/parser.c | 29 ++++++++++++++--------------- src/render.c | 7 ++++--- test/testText.c | 6 ++++++ 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/packet.c b/src/packet.c index c30d9fd..1b84dcc 100644 --- a/src/packet.c +++ b/src/packet.c @@ -4,6 +4,12 @@ #include +static inline +size_t psyc_getNumLength(size_t n) +{ + return n < 10 ? 1 : log10(n) + 1; +} + inline psycListFlag psyc_checkListLength (psycList *list) { @@ -37,7 +43,7 @@ psycListFlag psyc_getListLength (psycList *list) { if (i > 0) length++; // | - length += log10((double)list->elems[i].length) + 2 + list->elems[i].length; // length SP elem + length += psyc_getNumLength(list->elems[i].length) + 1 + list->elems[i].length; // length SP elem } } else @@ -69,8 +75,8 @@ size_t psyc_getModifierLength (psycModifier *m) m->name.length + 1 + // name\t m->value.length + 1; // value\n - if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed - length += log10((double)m->value.length) + 2; // SP length + if (m->flag == PSYC_MODIFIER_NEED_LENGTH && m->value.length) // add length of length if needed + length += psyc_getNumLength(m->value.length) + 1; // SP length return length; } @@ -121,12 +127,11 @@ size_t psyc_setPacketLength(psycPacket *p) // set total length: routing-header content |\n p->length = p->routingLength + p->contentLength + 2; - if (p->contentLength > 0) - { + if (p->contentLength > 0 || p->flag == PSYC_PACKET_NEED_LENGTH) p->length++; // add \n at the start of the content part - if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p->length += log10((double)p->contentLength) + 1; - } + + if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed + p->length += psyc_getNumLength(p->contentLength); return p->length; } diff --git a/src/parser.c b/src/parser.c index 7fd694f..2316b40 100644 --- a/src/parser.c +++ b/src/parser.c @@ -8,14 +8,13 @@ #include #include -#define PSYC_ADVANCE_CURSOR_OR_RETURN(ret) \ +#define ADVANCE_CURSOR_OR_RETURN(ret) \ if (++(state->cursor) >= state->buffer.length) \ { \ state->cursor = state->startc; \ return ret; \ } - /** * Determines if the argument is a glyph. * Glyphs are: : = + - ? ! @@ -82,7 +81,7 @@ psycParseRC psyc_parseKeyword (psycParseState* state, psycString* name) while (isKwChar(state->buffer.ptr[state->cursor])) { name->length++; // was a valid char, increase length - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } return name->length > 0 ? PSYC_PARSE_SUCCESS : PSYC_PARSE_ERROR; @@ -130,7 +129,7 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, psycString *name, psycString *value) { *oper = *(state->buffer.ptr + state->cursor); - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); psycParseRC ret = psyc_parseKeyword(state, name); if (ret == PSYC_PARSE_ERROR) @@ -147,14 +146,14 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, // If we're in the content part check if it's a binary var. if (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') // binary arg { // After SP the length follows. - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); if (isNumeric(state->buffer.ptr[state->cursor])) { do { length = 10 * length + state->buffer.ptr[state->cursor] - '0'; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); state->valueLength = length; @@ -177,13 +176,13 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper, } else if (state->buffer.ptr[state->cursor] == '\t') // simple arg { - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); value->ptr = state->buffer.ptr + state->cursor; while (state->buffer.ptr[state->cursor] != '\n') { value->length++; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } return PSYC_PARSE_SUCCESS; @@ -233,7 +232,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, { if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } // Each line of the header starts with a glyph, @@ -262,7 +261,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, do { state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } while (isNumeric(state->buffer.ptr[state->cursor])); } @@ -292,7 +291,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, } state->startc = state->cursor + 1; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); // fall thru case PSYC_PART_CONTENT: @@ -314,7 +313,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, { if (state->buffer.ptr[state->cursor] != '\n') return PSYC_PARSE_ERROR_MOD_NL; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } // Each line of the header starts with a glyph, @@ -361,7 +360,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, state->part = PSYC_PART_DATA; } else // otherwise keep it at the beginning of method - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); // fall thru } @@ -421,7 +420,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper, } } value->length++; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); } } @@ -505,7 +504,7 @@ psycParseListRC psyc_parseList (psycParseListState* state, psycString *name, do { state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0'; - PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); + ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); } while (isNumeric(state->buffer.ptr[state->cursor])); } diff --git a/src/render.c b/src/render.c index a5848c0..74ba859 100644 --- a/src/render.c +++ b/src/render.c @@ -82,8 +82,9 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) if (packet->flag == PSYC_PACKET_NEED_LENGTH) cur += itoa(packet->contentLength, buffer + cur, 10); - if (packet->entity.lines || packet->method.length || packet->data.length) - buffer[cur++] = '\n'; // start of content part if there's content + if (packet->flag == PSYC_PACKET_NEED_LENGTH || + packet->entity.lines || packet->method.length || packet->data.length) + buffer[cur++] = '\n'; // start of content part if there's content or length // render entity modifiers for (i = 0; i < packet->entity.lines; i++) @@ -94,11 +95,11 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen) memcpy(buffer + cur, packet->method.ptr, packet->method.length); cur += packet->method.length; buffer[cur++] = '\n'; + if (packet->data.length) // add data\n { memcpy(buffer + cur, packet->data.ptr, packet->data.length); cur += packet->data.length; - buffer[cur++] = '\n'; } } diff --git a/test/testText.c b/test/testText.c index 9fd3c1f..e5aff36 100644 --- a/test/testText.c +++ b/test/testText.c @@ -9,6 +9,8 @@ uint8_t verbose; psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value) { + if (verbose) + printf("> getValue: %.*s\n", (int)len, name); value->ptr = "Foo Bar"; value->length = 7; return PSYC_TEXT_VALUE_FOUND; @@ -16,6 +18,8 @@ psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value) psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value) { + if (verbose) + printf("> getValue: %.*s\n", (int)len, name); value->ptr = ""; value->length = 0; return PSYC_TEXT_VALUE_FOUND; @@ -23,6 +27,8 @@ psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value) psycTextValueRC getValueNotFound (const char *name, size_t len, psycString *value) { + if (verbose) + printf("> getValue: %.*s\n", (int)len, name); return PSYC_TEXT_VALUE_NOT_FOUND; }