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++;
while(*f)
{
if (*f == 'l') if (*f == 'l')
{ {
literal = 1; literal = 1;
f++; f++;
} }
if (*f == 'f') else if (*f == 'f')
{
f++; f++;
}
else break;
}
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++;
...@@ -141,12 +150,14 @@ UINT32 ssh_vformat_length(char *f, va_list args) ...@@ -141,12 +150,14 @@ 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;
if (atom[0])
{ /* Non empty */
for(i = 0; atom[i] > 0; i++) for(i = 0; atom[i] > 0; i++)
length += get_atom_length(atom[i]) + 1; length += get_atom_length(atom[i]) + 1;
/* One ','-character less than the number of atoms */ /* One ','-character less than the number of atoms */
length--; length--;
}
if (!literal) if (!literal)
length += 4; length += 4;
f++; f++;
...@@ -179,10 +190,10 @@ UINT32 ssh_vformat_length(char *f, va_list args) ...@@ -179,10 +190,10 @@ UINT32 ssh_vformat_length(char *f, va_list args)
if (!literal) if (!literal)
length += 4; length += 4;
f++; f++;
}
break; break;
} }
} }
}
else else
{ {
length++; length++;
...@@ -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,16 +214,20 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -201,16 +214,20 @@ 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++;
while(*f)
{
if (*f == 'l') if (*f == 'l')
{ {
literal = 1; literal = 1;
f++; f++;
} }
if (*f == 'f') else if (*f == 'f')
{ {
do_free = 1; do_free = 1;
f++; f++;
} }
else break;
}
switch(*f) switch(*f)
{ {
default: default:
...@@ -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,13 +426,15 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args) ...@@ -401,13 +426,15 @@ void ssh_vformat(char *f, UINT8 *buffer, va_list args)
} }
f++; f++;
}
break; break;
} }
} }
}
else else
{ {
*buffer++ = *f++; *buffer++ = *f++;
} }
} }
return buffer - start;
} }
...@@ -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