fix for 0 length content/modifiers

This commit is contained in:
tg(x) 2011-05-04 17:46:20 +02:00
parent a67cc24c40
commit e7a4df6180
4 changed files with 37 additions and 26 deletions

View File

@ -4,6 +4,12 @@
#include <math.h>
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;
}

View File

@ -8,14 +8,13 @@
#include <psyc/lib.h>
#include <psyc/parser.h>
#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]));
}

View File

@ -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';
}
}

View File

@ -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;
}