mirror of
git://git.psyc.eu/libpsyc
synced 2024-08-15 03:19:02 +00:00
fix for 0 length content/modifiers
This commit is contained in:
parent
a67cc24c40
commit
e7a4df6180
4 changed files with 37 additions and 26 deletions
21
src/packet.c
21
src/packet.c
|
@ -4,6 +4,12 @@
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
static inline
|
||||||
|
size_t psyc_getNumLength(size_t n)
|
||||||
|
{
|
||||||
|
return n < 10 ? 1 : log10(n) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
psycListFlag psyc_checkListLength (psycList *list)
|
psycListFlag psyc_checkListLength (psycList *list)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +43,7 @@ psycListFlag psyc_getListLength (psycList *list)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
length++; // |
|
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
|
else
|
||||||
|
@ -69,8 +75,8 @@ size_t psyc_getModifierLength (psycModifier *m)
|
||||||
m->name.length + 1 + // name\t
|
m->name.length + 1 + // name\t
|
||||||
m->value.length + 1; // value\n
|
m->value.length + 1; // value\n
|
||||||
|
|
||||||
if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed
|
if (m->flag == PSYC_MODIFIER_NEED_LENGTH && m->value.length) // add length of length if needed
|
||||||
length += log10((double)m->value.length) + 2; // SP length
|
length += psyc_getNumLength(m->value.length) + 1; // SP length
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
@ -121,12 +127,11 @@ size_t psyc_setPacketLength(psycPacket *p)
|
||||||
// set total length: routing-header content |\n
|
// set total length: routing-header content |\n
|
||||||
p->length = p->routingLength + p->contentLength + 2;
|
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
|
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;
|
return p->length;
|
||||||
}
|
}
|
||||||
|
|
29
src/parser.c
29
src/parser.c
|
@ -8,14 +8,13 @@
|
||||||
#include <psyc/lib.h>
|
#include <psyc/lib.h>
|
||||||
#include <psyc/parser.h>
|
#include <psyc/parser.h>
|
||||||
|
|
||||||
#define PSYC_ADVANCE_CURSOR_OR_RETURN(ret) \
|
#define ADVANCE_CURSOR_OR_RETURN(ret) \
|
||||||
if (++(state->cursor) >= state->buffer.length) \
|
if (++(state->cursor) >= state->buffer.length) \
|
||||||
{ \
|
{ \
|
||||||
state->cursor = state->startc; \
|
state->cursor = state->startc; \
|
||||||
return ret; \
|
return ret; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the argument is a glyph.
|
* Determines if the argument is a glyph.
|
||||||
* Glyphs are: : = + - ? !
|
* Glyphs are: : = + - ? !
|
||||||
|
@ -82,7 +81,7 @@ psycParseRC psyc_parseKeyword (psycParseState* state, psycString* name)
|
||||||
while (isKwChar(state->buffer.ptr[state->cursor]))
|
while (isKwChar(state->buffer.ptr[state->cursor]))
|
||||||
{
|
{
|
||||||
name->length++; // was a valid char, increase length
|
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;
|
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)
|
psycString *name, psycString *value)
|
||||||
{
|
{
|
||||||
*oper = *(state->buffer.ptr + state->cursor);
|
*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);
|
psycParseRC ret = psyc_parseKeyword(state, name);
|
||||||
if (ret == PSYC_PARSE_ERROR)
|
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 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
|
if (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') // binary arg
|
||||||
{ // After SP the length follows.
|
{ // 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]))
|
if (isNumeric(state->buffer.ptr[state->cursor]))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
length = 10 * length + state->buffer.ptr[state->cursor] - '0';
|
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]));
|
while (isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
state->valueLength = length;
|
state->valueLength = length;
|
||||||
|
@ -177,13 +176,13 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper,
|
||||||
}
|
}
|
||||||
else if (state->buffer.ptr[state->cursor] == '\t') // simple arg
|
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;
|
value->ptr = state->buffer.ptr + state->cursor;
|
||||||
|
|
||||||
while (state->buffer.ptr[state->cursor] != '\n')
|
while (state->buffer.ptr[state->cursor] != '\n')
|
||||||
{
|
{
|
||||||
value->length++;
|
value->length++;
|
||||||
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PSYC_PARSE_SUCCESS;
|
return PSYC_PARSE_SUCCESS;
|
||||||
|
@ -233,7 +232,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
||||||
{
|
{
|
||||||
if (state->buffer.ptr[state->cursor] != '\n')
|
if (state->buffer.ptr[state->cursor] != '\n')
|
||||||
return PSYC_PARSE_ERROR_MOD_NL;
|
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,
|
// Each line of the header starts with a glyph,
|
||||||
|
@ -262,7 +261,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0';
|
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]));
|
while (isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
}
|
}
|
||||||
|
@ -292,7 +291,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
||||||
}
|
}
|
||||||
|
|
||||||
state->startc = state->cursor + 1;
|
state->startc = state->cursor + 1;
|
||||||
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
// fall thru
|
// fall thru
|
||||||
|
|
||||||
case PSYC_PART_CONTENT:
|
case PSYC_PART_CONTENT:
|
||||||
|
@ -314,7 +313,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
||||||
{
|
{
|
||||||
if (state->buffer.ptr[state->cursor] != '\n')
|
if (state->buffer.ptr[state->cursor] != '\n')
|
||||||
return PSYC_PARSE_ERROR_MOD_NL;
|
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,
|
// 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;
|
state->part = PSYC_PART_DATA;
|
||||||
}
|
}
|
||||||
else // otherwise keep it at the beginning of method
|
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
|
// fall thru
|
||||||
}
|
}
|
||||||
|
@ -421,7 +420,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value->length++;
|
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
|
do
|
||||||
{
|
{
|
||||||
state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0';
|
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]));
|
while (isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,8 +82,9 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen)
|
||||||
if (packet->flag == PSYC_PACKET_NEED_LENGTH)
|
if (packet->flag == PSYC_PACKET_NEED_LENGTH)
|
||||||
cur += itoa(packet->contentLength, buffer + cur, 10);
|
cur += itoa(packet->contentLength, buffer + cur, 10);
|
||||||
|
|
||||||
if (packet->entity.lines || packet->method.length || packet->data.length)
|
if (packet->flag == PSYC_PACKET_NEED_LENGTH ||
|
||||||
buffer[cur++] = '\n'; // start of content part if there's content
|
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
|
// render entity modifiers
|
||||||
for (i = 0; i < packet->entity.lines; i++)
|
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);
|
memcpy(buffer + cur, packet->method.ptr, packet->method.length);
|
||||||
cur += packet->method.length;
|
cur += packet->method.length;
|
||||||
buffer[cur++] = '\n';
|
buffer[cur++] = '\n';
|
||||||
|
|
||||||
if (packet->data.length) // add data\n
|
if (packet->data.length) // add data\n
|
||||||
{
|
{
|
||||||
memcpy(buffer + cur, packet->data.ptr, packet->data.length);
|
memcpy(buffer + cur, packet->data.ptr, packet->data.length);
|
||||||
cur += packet->data.length;
|
cur += packet->data.length;
|
||||||
|
|
||||||
buffer[cur++] = '\n';
|
buffer[cur++] = '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ uint8_t verbose;
|
||||||
|
|
||||||
psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value)
|
psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value)
|
||||||
{
|
{
|
||||||
|
if (verbose)
|
||||||
|
printf("> getValue: %.*s\n", (int)len, name);
|
||||||
value->ptr = "Foo Bar";
|
value->ptr = "Foo Bar";
|
||||||
value->length = 7;
|
value->length = 7;
|
||||||
return PSYC_TEXT_VALUE_FOUND;
|
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)
|
psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value)
|
||||||
{
|
{
|
||||||
|
if (verbose)
|
||||||
|
printf("> getValue: %.*s\n", (int)len, name);
|
||||||
value->ptr = "";
|
value->ptr = "";
|
||||||
value->length = 0;
|
value->length = 0;
|
||||||
return PSYC_TEXT_VALUE_FOUND;
|
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)
|
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;
|
return PSYC_TEXT_VALUE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue