MOS Source Code
Loading...
Searching...
No Matches
raw_decode.c
Go to the documentation of this file.
1/* A small tool that decodes a raw binary message, while providing useful
2 * info on corrupted messages also. */
3
4/* Define _ISOC99_SOURCE to get snprintf() even though otherwise in ansi-C mode */
5#define _ISOC99_SOURCE 1
6
7#include <stdio.h>
8#include <string.h>
9#include <pb_decode.h>
10#include "test_helpers.h"
11
12#define HISTORY_LEN 32
14static int g_position;
15
16/* This binds the pb_istream_t to stdin and logs the most recent bytes read. */
17bool callback(pb_istream_t *stream, uint8_t *buf, size_t count)
18{
19 FILE *file = (FILE*)stream->state;
20 size_t len = fread(buf, 1, count, file);
21
22 if (len < HISTORY_LEN)
23 {
25 memcpy(g_history + HISTORY_LEN - len, buf, len);
26 }
27 else
28 {
30 }
31
32 g_position += len;
33
34 if (len == count)
35 {
36 return true;
37 }
38 else
39 {
40 stream->bytes_left = 0;
41 return false;
42 }
43}
44
45void print_history(int position)
46{
47 int i;
48
49 if (position < g_position - HISTORY_LEN)
50 position = g_position - HISTORY_LEN;
51
52 printf("LATEST BYTES READ (%d to %d): ", position, g_position);
53
54 for (i = HISTORY_LEN - (g_position - position); i < HISTORY_LEN; i++)
55 {
56 printf("%02x ", g_history[i]);
57 }
58
59 printf("\n");
60}
61
62bool raw_decode(pb_istream_t *stream, const char *indent)
63{
64 const char *wiretypes[8] = {"VARINT", "64BIT", "STRING", "SGRP", "EGRP", "32BIT", "????", "????"};
65
66 while (stream->bytes_left)
67 {
68 uint32_t tag;
69 pb_wire_type_t wire_type;
70 bool eof;
71 int position = g_position;
72
73 if (!pb_decode_tag(stream, &wire_type, &tag, &eof))
74 {
75 if (eof)
76 {
77 break;
78 }
79 else
80 {
81 printf("ERROR: Failed to parse tag: %s\n", PB_GET_ERROR(stream));
82 print_history(position);
83 return false;
84 }
85 }
86
87 if (tag == 0)
88 {
89 printf("%sterminating on zero tag\n", indent);
90 return true;
91 }
92
93 printf("%sAt %d: field tag %d, wire type %d (%s)",
94 indent, position, (int)tag, wire_type, wiretypes[wire_type]);
95
96 if (wire_type == PB_WT_VARINT)
97 {
98 uint64_t value;
99 position = g_position;
100 if (!pb_decode_varint(stream, &value))
101 {
102 printf("\n%sERROR: Failed to parse varint: %s\n", indent, PB_GET_ERROR(stream));
103 print_history(position);
104 return false;
105 }
106
107 printf(", varint value (%d bytes): %llu\n",
108 g_position - position, (unsigned long long)value);
109 }
110 else if (wire_type == PB_WT_64BIT)
111 {
112 uint64_t value;
113 position = g_position;
114 if (!pb_decode_fixed64(stream, &value))
115 {
116 printf("\n%sERROR: Failed to parse fixed64: %s\n", indent, PB_GET_ERROR(stream));
117 print_history(position);
118 return false;
119 }
120
121 printf(", fixed64 value (%d bytes): 0x%016llx\n",
122 g_position - position, (unsigned long long)value);
123 }
124 else if (wire_type == PB_WT_32BIT)
125 {
126 uint32_t value;
127 position = g_position;
128 if (!pb_decode_fixed32(stream, &value))
129 {
130 printf("\n%sERROR: Failed to parse fixed32: %s\n", indent, PB_GET_ERROR(stream));
131 print_history(position);
132 return false;
133 }
134
135 printf(", fixed32 value (%d bytes): 0x%08lx\n",
136 g_position - position, (unsigned long)value);
137 }
138 else if (wire_type == PB_WT_STRING)
139 {
140 pb_istream_t substream;
141 position = g_position;
142 if (!pb_make_string_substream(stream, &substream))
143 {
144 printf("ERROR: Failed to parse string length: %s\n", PB_GET_ERROR(stream));
145 print_history(position);
146 return false;
147 }
148 else
149 {
150
151 if (substream.bytes_left == 0)
152 {
153 printf(", empty string\n");
154 }
155 else
156 {
157 char prefix[8];
158 snprintf(prefix, sizeof(prefix), "f%d> ", (int)tag);
159
160 printf(", string len %d bytes, attempting recursive decode\n",
161 (int)substream.bytes_left);
162
163 if (!raw_decode(&substream, prefix))
164 {
165 printf("%sfield %d: recursive decode failed, continuing with upper level\n\n",
166 indent, (int)tag);
167 }
168
169 pb_close_string_substream(stream, &substream);
170 }
171 }
172 }
173 else
174 {
175 printf("\n");
176 }
177 }
178
179 return true;
180}
181
182int main()
183{
184 pb_istream_t stream = {&callback, NULL, SIZE_MAX};
185 stream.state = stdin;
187
188 if (!raw_decode(&stream, ""))
189 {
190 return 1;
191 } else {
192 return 0;
193 }
194}
MOSAPI void * memmove(void *dest, const void *src, size_t n)
Definition mos_string.c:111
size_t fread(void *__restrict ptr, size_t size, size_t nmemb, FILE *__restrict stream)
struct _FILE FILE
Definition mos_stdio.h:24
#define stdin
Definition mos_stdio.h:30
int snprintf(char *__restrict str, size_t size, const char *__restrict format,...)
Definition mos_stdio.c:16
uint_least8_t pb_byte_t
Definition pb.h:227
#define PB_GET_ERROR(stream)
Definition pb.h:891
pb_wire_type_t
Definition pb.h:420
@ PB_WT_VARINT
Definition pb.h:421
@ PB_WT_32BIT
Definition pb.h:424
@ PB_WT_STRING
Definition pb.h:423
@ PB_WT_64BIT
Definition pb.h:422
bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
Definition pb_decode.c:243
bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
Definition pb_decode.c:1370
bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream)
Definition pb_decode.c:362
bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
Definition pb_decode.c:377
bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
Definition pb_decode.c:1393
bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof)
Definition pb_decode.c:291
static void * memcpy(void *s1, const void *s2, size_t n)
Definition pb_syshdr.h:90
#define NULL
Definition pb_syshdr.h:46
unsigned int uint32_t
Definition pb_syshdr.h:24
unsigned long long uint64_t
Definition pb_syshdr.h:26
unsigned char uint8_t
Definition pb_syshdr.h:20
static int g_position
Definition raw_decode.c:14
void print_history(int position)
Definition raw_decode.c:45
static pb_byte_t g_history[32]
Definition raw_decode.c:13
bool callback(pb_istream_t *stream, uint8_t *buf, size_t count)
Definition raw_decode.c:17
bool raw_decode(pb_istream_t *stream, const char *indent)
Definition raw_decode.c:62
#define HISTORY_LEN
Definition raw_decode.c:12
int main()
Definition raw_decode.c:182
#define SET_BINARY_MODE(file)