Commit d072255f authored by Niels Möller's avatar Niels Möller
Browse files

Fixed bug in formatting empty %A lists, and sanity checks on the

computed length.

Rev: src/format.c:1.12
Rev: src/format.h:1.11
parent 4fd8120f
...@@ -43,9 +43,11 @@ struct lsh_string *ssh_format(char *format, ...) ...@@ -43,9 +43,11 @@ struct lsh_string *ssh_format(char *format, ...)
packet = lsh_string_alloc(length); packet = lsh_string_alloc(length);
va_start(args, format); va_start(args, format);
ssh_vformat(format, packet->data, args); length = ssh_vformat(format, packet->data, args);
va_end(args); va_end(args);
assert(length == packet->length);
return packet; return packet;
} }
...@@ -59,13 +61,19 @@ UINT32 ssh_vformat_length(char *f, va_list args) ...@@ -59,13 +61,19 @@ UINT32 ssh_vformat_length(char *f, va_list args)
{ {
int literal = 0; int literal = 0;
f++; f++;
if (*f == 'l') while(*f)
{ {
literal = 1; if (*f == 'l')
f++; {
literal = 1;
f++;
}
else if (*f == 'f')
{
f++;
}
else break;
} }
if (*f == 'f')
f++;
switch(*f) switch(*f)
{ {
...@@ -97,8 +105,9 @@ UINT32 ssh_vformat_length(char *f, va_list args) ...@@ -97,8 +105,9 @@ UINT32 ssh_vformat_length(char *f, va_list args)
if (!literal) if (!literal)
length += 4; length += 4;
break;
} }
break;
case 'S': case 'S':
length += va_arg(args, struct lsh_string *)->length; length += va_arg(args, struct lsh_string *)->length;
f++; f++;
...@@ -115,7 +124,7 @@ UINT32 ssh_vformat_length(char *f, va_list args) ...@@ -115,7 +124,7 @@ UINT32 ssh_vformat_length(char *f, va_list args)
length += 4; length += 4;
break; break;
case 'r': case 'r':
length += va_arg(args, struct lsh_string *)->length; length += va_arg(args, UINT32);
(void) va_arg(args, UINT8 **); /* pointer */ (void) va_arg(args, UINT8 **); /* pointer */
f++; f++;
...@@ -140,13 +149,15 @@ UINT32 ssh_vformat_length(char *f, va_list args) ...@@ -140,13 +149,15 @@ UINT32 ssh_vformat_length(char *f, va_list args)
{ {
int *atom = va_arg(args, int *); int *atom = va_arg(args, int *);
int i; int i;
for(i = 0; atom[i] > 0; i++)
length += get_atom_length(atom[i]) + 1;
/* One ','-character less than the number of atoms */ if (atom[0])
length--; { /* Non empty */
for(i = 0; atom[i] > 0; i++)
length += get_atom_length(atom[i]) + 1;
/* One ','-character less than the number of atoms */
length--;
}
if (!literal) if (!literal)
length += 4; length += 4;
f++; f++;
...@@ -179,8 +190,8 @@ UINT32 ssh_vformat_length(char *f, va_list args) ...@@ -179,8 +190,8 @@ UINT32 ssh_vformat_length(char *f, va_list args)
if (!literal) if (!literal)
length += 4; length += 4;
f++; f++;
break;
} }
break;
} }
} }
else else
...@@ -192,8 +203,10 @@ UINT32 ssh_vformat_length(char *f, va_list args) ...@@ -192,8 +203,10 @@ UINT32 ssh_vformat_length(char *f, va_list args)
return length; return length;
} }
void ssh_vformat(char *f, UINT8 *buffer, va_list args) UINT32 ssh_vformat(char *f, UINT8 *buffer, va_list args)
{ {
UINT8 *start = buffer;
while(*f) while(*f)
{ {
if (*f == '%') if (*f == '%')
...@@ -201,15 +214,19 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -201,15 +214,19 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
int literal = 0; int literal = 0;
int do_free = 0; int do_free = 0;
f++; f++;
if (*f == 'l') while(*f)
{ {
literal = 1; if (*f == 'l')
f++; {
} literal = 1;
if (*f == 'f') f++;
{ }
do_free = 1; else if (*f == 'f')
f++; {
do_free = 1;
f++;
}
else break;
} }
switch(*f) switch(*f)
{ {
...@@ -218,12 +235,14 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -218,12 +235,14 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
break; break;
case 'c': case 'c':
*buffer++ = va_arg(args, UINT8); *buffer++ = va_arg(args, int);
f++; f++;
break; break;
case '%': case '%':
*buffer++ = '%'; *buffer++ = '%';
f++; f++;
break; break;
case 'i': case 'i':
...@@ -232,8 +251,9 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -232,8 +251,9 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
WRITE_UINT32(buffer, i); WRITE_UINT32(buffer, i);
buffer += 4; buffer += 4;
f++; f++;
break;
} }
break;
case 's': case 's':
{ {
UINT32 length = va_arg(args, UINT32); UINT32 length = va_arg(args, UINT32);
...@@ -248,8 +268,9 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -248,8 +268,9 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
memcpy(buffer, data, length); memcpy(buffer, data, length);
buffer += length; buffer += length;
f++; f++;
break;
} }
break;
case 'S': case 'S':
{ {
struct lsh_string *s = va_arg(args, struct lsh_string *); struct lsh_string *s = va_arg(args, struct lsh_string *);
...@@ -266,6 +287,7 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -266,6 +287,7 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
if (do_free) if (do_free)
lsh_string_free(s); lsh_string_free(s);
f++; f++;
break; break;
} }
case 'z': case 'z':
...@@ -281,6 +303,7 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -281,6 +303,7 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
memcpy(buffer, s, length); memcpy(buffer, s, length);
buffer += length; buffer += length;
f++; f++;
break; break;
} }
case 'r': case 'r':
...@@ -298,6 +321,8 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -298,6 +321,8 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
*p = buffer; *p = buffer;
buffer += length; buffer += length;
f++; f++;
break;
} }
case 'a': case 'a':
...@@ -318,6 +343,7 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -318,6 +343,7 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
memcpy(buffer, get_atom_name(atom), length); memcpy(buffer, get_atom_name(atom), length);
buffer += length; buffer += length;
f++; f++;
break; break;
} }
#if 0 #if 0
...@@ -365,10 +391,9 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -365,10 +391,9 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
if (atom[0] > 0) if (atom[0] > 0)
{ {
UINT32 length = get_atom_length(*atom); UINT32 length = get_atom_length(atom[0]);
memcpy(buffer, get_atom_name(*atom), length); memcpy(buffer, get_atom_name(atom[0]), length);
buffer += length; buffer += length;
atom ++;
for (i = 1; atom[i] > 0; i++) for (i = 1; atom[i] > 0; i++)
{ {
...@@ -401,8 +426,9 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -401,8 +426,9 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
} }
f++; f++;
break;
} }
break;
} }
} }
else else
...@@ -410,4 +436,5 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -410,4 +436,5 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
*buffer++ = *f++; *buffer++ = *f++;
} }
} }
return buffer - start;
} }
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
* %z Insert a string, using a null-terminated argument. * %z Insert a string, using a null-terminated argument.
* *
* %r Reserves space in the string, and stores a pointer to this space * %r Reserves space in the string, and stores a pointer to this space
* into the given UINT8 ** argument. * into the given UINT8 ** argument.
* *
* %a Insert a string containing one atom. * %a Insert a string containing one atom.
* *
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
* Applicable to %S only. */ * Applicable to %S only. */
UINT32 ssh_vformat_length(char *format, va_list args); UINT32 ssh_vformat_length(char *format, va_list args);
void ssh_vformat(char *format, UINT8 *buffer, va_list args); UINT32 ssh_vformat(char *format, UINT8 *buffer, va_list args);
struct lsh_string *ssh_format(char *format, ...); struct lsh_string *ssh_format(char *format, ...);
/* Short cut */ /* Short cut */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment