#include <stdio.h>#include <stddef.h>#include <stdint.h>#include <setjmp.h>#include <string.h>#include <stdarg.h>#include <cmocka.h> struct strings { //# decoder encoder char a[8]; //#1 char b[1]; //#2 char c[2]; //#3 char d[8]; //#4 truncate char *s; //#5 truncate char *s2; //#6 char *s3; //#7 truncate char buf[12]; //# buffer=here int x;}; struct strings2 { //# decoder encoder char *a; //#1 char *b[4]; //#2 num_at=b_num callback=longest char *c; //#3 const char *cnst; //#4 num_at=cnst_num char buf[28]; //# buffer=here int b_num; int cnst_num; int longest; //#}; #include "test_strings.pb.h" static intlongest(struct strings2 *s2, char *str, int len){ assert_int_equal(strlen(str), len); if(s2->longest < len) s2->longest = len; return PB_CALLBACK_OK;} voidtest_strings_default_pretty(void **state){ struct strings s; char buf[128]; (void)state; memset(&s, 0, sizeof(s)); assert_non_null(pb_seprint_strings(&s, buf, buf+sizeof(buf), 0, 0)); assert_string_equal( buf, "{}" );} voidtest_strings_max_length_pretty(void **state){ struct strings s = { .a = "1234567", .b = "", .c = "a", .d = "ABCDEFG", .buf = "\x9\0abcdefghi", .s2 = NULL, .s3 = NULL, .x = 0, }; char buf[128]; (void)state; s.s = s.buf+2; assert_non_null(pb_seprint_strings(&s, buf, buf+sizeof(buf), 0, 1)); assert_string_equal( buf, "{\n" " a = \"1234567\", // #1\n" " c = \"a\", // #3\n" " d = \"ABCDEFG\", // #4\n" " s = \"abcdefghi\", // #5\n" "}" );} voidtest_strings_max_length_encode(void **state){ struct strings s = { .a = "1234567", .b = "", .c = "a", .d = "ABCDEFG", .s = "abcdefg", .s2 = NULL, .s3 = NULL, .x = 0, }; // a:"1234567", c:"a", d:"ABCDEFG", s:"abcdefg" const uint8_t raw[] = { 0x0a, 0x07, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x1a, 0x01, 0x61, 0x22, 0x07, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x2a, 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, }; uint8_t buf[sizeof(raw)]; (void)state; assert_ptr_equal(pb_encode_strings(&s, buf, buf+sizeof(buf)), buf+sizeof(raw)); assert_memory_equal(raw, buf, sizeof(raw));} voidtest_strings_truncate_decode(void **state){ // b:"", d:"1234567890", s:"abcde", s:"jihgfedcba", s2:"fg", s3:"h" const uint8_t raw[] = { 0x12, 0x00, 0x22, 0x0a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2a, 0x05, 0x61, 0x62, 0x63, 0x64, 0x65, 0x2a, 0x0a, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x32, 0x02, 0x66, 0x67, 0x3a, 0x01, 0x68, }; struct strings s; (void)state; s.x = -1; assert_ptr_equal(pb_decode_strings(&s, raw, raw+sizeof(raw)), raw+sizeof(raw)); assert_string_equal(s.a, ""); assert_string_equal(s.b, ""); assert_string_equal(s.c, ""); assert_string_equal(s.d, "1234567"); assert_non_null(s.s); assert_string_equal(s.s, "abcde"); assert_non_null(s.s2); assert_string_equal(s.s2, "fg"); assert_null(s.s3); assert_int_equal(s.x, -1);} voidtest_strings_decode(void **state){ // a:"ab", b:"cd", b:"efg", b:"hi", c:"jkl" const uint8_t raw[] = { 0x0a, 0x02, 0x61, 0x62, 0x12, 0x02, 0x63, 0x64, 0x12, 0x03, 0x65, 0x66, 0x67, 0x12, 0x02, 0x68, 0x69, 0x1a, 0x03, 0x6a, 0x6b, 0x6c, }; struct strings2 s; (void)state; s.longest = 0; assert_ptr_equal(pb_decode_strings2(&s, raw, raw+sizeof(raw)), raw+sizeof(raw)); assert_non_null(s.a); assert_string_equal(s.a, "ab"); assert_int_equal(s.b_num, 3); assert_non_null(s.b[0]); assert_string_equal(s.b[0], "cd"); assert_non_null(s.b[1]); assert_string_equal(s.b[1], "efg"); assert_non_null(s.b[2]); assert_string_equal(s.b[2], "hi"); assert_string_equal(s.c, "jkl"); assert_int_equal(s.longest, 3);} voidtest_strings_array_overflow_decode(void **state){ // b:"a", b:"b", b:"c", b:"d", b:"e", cnst:"A really long string here, it does not fit." const uint8_t raw[] = { 0x12, 0x01, 0x61, 0x12, 0x01, 0x62, 0x12, 0x01, 0x63, 0x12, 0x01, 0x64, 0x12, 0x01, 0x65, 0x22, 0x2b, 0x41, 0x20, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x72, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x69, 0x74, 0x2e, }; struct strings2 s; char buf[44]; (void)state; s.longest = 0; assert_ptr_equal(pb_decode_strings2(&s, raw, raw+sizeof(raw)), raw+sizeof(raw)); assert_null(s.a); assert_int_equal(s.b_num, 4); assert_non_null(s.b[0]); assert_string_equal(s.b[0], "a"); assert_non_null(s.b[1]); assert_string_equal(s.b[1], "b"); assert_non_null(s.b[2]); assert_string_equal(s.b[2], "c"); assert_non_null(s.b[3]); assert_string_equal(s.b[3], "d"); assert_non_null(s.cnst); assert_int_equal(s.cnst_num, 43); memmove(buf, s.cnst, 43); buf[43] = 0; assert_string_equal(buf, "A really long string here, it does not fit."); assert_int_equal(s.longest, 1);}
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <setjmp.h>
#include <string.h>
#include <stdarg.h>
#include <cmocka.h>
struct strings { //# decoder encoder
char a[8]; //#1
char b[1]; //#2
char c[2]; //#3
char d[8]; //#4 truncate
char *s; //#5 truncate
char *s2; //#6
char *s3; //#7 truncate
char buf[12]; //# buffer=here
int x;
};
struct strings2 { //# decoder encoder
char *a; //#1
char *b[4]; //#2 num_at=b_num callback=longest
char *c; //#3
const char *cnst; //#4 num_at=cnst_num
char buf[28]; //# buffer=here
int b_num;
int cnst_num;
int longest; //#
};
#include "test_strings.pb.h"
static int
longest(struct strings2 *s2, char *str, int len)
{
assert_int_equal(strlen(str), len);
if(s2->longest < len)
s2->longest = len;
return PB_CALLBACK_OK;
}
void
test_strings_default_pretty(void **state)
{
struct strings s;
char buf[128];
(void)state;
memset(&s, 0, sizeof(s));
assert_non_null(pb_seprint_strings(&s, buf, buf+sizeof(buf), 0, 0));
assert_string_equal(
buf,
"{}"
);
}
void
test_strings_max_length_pretty(void **state)
{
struct strings s = {
.a = "1234567",
.b = "",
.c = "a",
.d = "ABCDEFG",
.buf = "\x9\0abcdefghi",
.s2 = NULL,
.s3 = NULL,
.x = 0,
};
char buf[128];
(void)state;
s.s = s.buf+2;
assert_non_null(pb_seprint_strings(&s, buf, buf+sizeof(buf), 0, 1));
assert_string_equal(
buf,
"{\n"
" a = \"1234567\", // #1\n"
" c = \"a\", // #3\n"
" d = \"ABCDEFG\", // #4\n"
" s = \"abcdefghi\", // #5\n"
"}"
);
}
void
test_strings_max_length_encode(void **state)
{
struct strings s = {
.a = "1234567",
.b = "",
.c = "a",
.d = "ABCDEFG",
.s = "abcdefg",
.s2 = NULL,
.s3 = NULL,
.x = 0,
};
// a:"1234567", c:"a", d:"ABCDEFG", s:"abcdefg"
const uint8_t raw[] = {
0x0a, 0x07, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x1a, 0x01, 0x61, 0x22, 0x07, 0x41, 0x42,
0x43, 0x44, 0x45, 0x46, 0x47, 0x2a, 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
};
uint8_t buf[sizeof(raw)];
(void)state;
assert_ptr_equal(pb_encode_strings(&s, buf, buf+sizeof(buf)), buf+sizeof(raw));
assert_memory_equal(raw, buf, sizeof(raw));
}
void
test_strings_truncate_decode(void **state)
{
// b:"", d:"1234567890", s:"abcde", s:"jihgfedcba", s2:"fg", s3:"h"
const uint8_t raw[] = {
0x12, 0x00, 0x22, 0x0a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2a, 0x05,
0x61, 0x62, 0x63, 0x64, 0x65, 0x2a, 0x0a, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62,
0x61, 0x32, 0x02, 0x66, 0x67, 0x3a, 0x01, 0x68,
};
struct strings s;
(void)state;
s.x = -1;
assert_ptr_equal(pb_decode_strings(&s, raw, raw+sizeof(raw)), raw+sizeof(raw));
assert_string_equal(s.a, "");
assert_string_equal(s.b, "");
assert_string_equal(s.c, "");
assert_string_equal(s.d, "1234567");
assert_non_null(s.s);
assert_string_equal(s.s, "abcde");
assert_non_null(s.s2);
assert_string_equal(s.s2, "fg");
assert_null(s.s3);
assert_int_equal(s.x, -1);
}
void
test_strings_decode(void **state)
{
// a:"ab", b:"cd", b:"efg", b:"hi", c:"jkl"
const uint8_t raw[] = {
0x0a, 0x02, 0x61, 0x62, 0x12, 0x02, 0x63, 0x64, 0x12, 0x03, 0x65, 0x66, 0x67, 0x12, 0x02, 0x68,
0x69, 0x1a, 0x03, 0x6a, 0x6b, 0x6c,
};
struct strings2 s;
(void)state;
s.longest = 0;
assert_ptr_equal(pb_decode_strings2(&s, raw, raw+sizeof(raw)), raw+sizeof(raw));
assert_non_null(s.a);
assert_string_equal(s.a, "ab");
assert_int_equal(s.b_num, 3);
assert_non_null(s.b[0]);
assert_string_equal(s.b[0], "cd");
assert_non_null(s.b[1]);
assert_string_equal(s.b[1], "efg");
assert_non_null(s.b[2]);
assert_string_equal(s.b[2], "hi");
assert_string_equal(s.c, "jkl");
assert_int_equal(s.longest, 3);
}
void
test_strings_array_overflow_decode(void **state)
{
// b:"a", b:"b", b:"c", b:"d", b:"e", cnst:"A really long string here, it does not fit."
const uint8_t raw[] = {
0x12, 0x01, 0x61, 0x12, 0x01, 0x62, 0x12, 0x01, 0x63, 0x12, 0x01, 0x64, 0x12, 0x01, 0x65, 0x22,
0x2b, 0x41, 0x20, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x73,
0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x72, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x64,
0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x69, 0x74, 0x2e,
};
struct strings2 s;
char buf[44];
(void)state;
s.longest = 0;
assert_ptr_equal(pb_decode_strings2(&s, raw, raw+sizeof(raw)), raw+sizeof(raw));
assert_null(s.a);
assert_int_equal(s.b_num, 4);
assert_non_null(s.b[0]);
assert_string_equal(s.b[0], "a");
assert_non_null(s.b[1]);
assert_string_equal(s.b[1], "b");
assert_non_null(s.b[2]);
assert_string_equal(s.b[2], "c");
assert_non_null(s.b[3]);
assert_string_equal(s.b[3], "d");
assert_non_null(s.cnst);
assert_int_equal(s.cnst_num, 43);
memmove(buf, s.cnst, 43);
buf[43] = 0;
assert_string_equal(buf, "A really long string here, it does not fit.");
assert_int_equal(s.longest, 1);
}