diff --git a/q.c b/q.c index 0669269..2855a22 100644 --- a/q.c +++ b/q.c @@ -1058,6 +1058,8 @@ static ray_t *q_des_obj(uint8_t **buf, int64_t *len) { case Q_XT: { /* table = attrs(0) + dict_marker(99) + keys + values */ Q_NEED(2); + if ((*buf)[0] != 0 || (*buf)[1] != Q_XD) + return ray_error("q: malformed table marker", NULL); (*buf) += 2; *len -= 2; ray_t *keys = q_des_obj(buf, len); @@ -1373,7 +1375,9 @@ ray_t *q_decode(uint8_t *resp, int64_t resp_len, int compressed, char *err, free(decompressed); if (result == NULL) q_set_err(err, errlen, "q: deserialization returned null"); - else if (remaining != 0) { + else if (RAY_IS_ERR(result)) { + return result; + } else if (remaining != 0) { q_release_any(result); q_set_err(err, errlen, "q: trailing bytes after object"); return NULL; diff --git a/test/driver.c b/test/driver.c index 8bdf204..008918c 100644 --- a/test/driver.c +++ b/test/driver.c @@ -333,6 +333,21 @@ static int run_codec_selftest(void) { } release_any(r); + err[0] = '\0'; + uint8_t bad_table_marker[] = {98, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; + r = q_decode(bad_table_marker, (int64_t)sizeof bad_table_marker, 0, err, + sizeof err); + ray_t *rs = r ? ray_fmt(r, 0) : NULL; + const char *rp = rs ? ray_str_ptr(rs) : err; + if (r == NULL || !RAY_IS_ERR(r) || strstr(rp, "q: malf") == NULL) { + fprintf(stderr, "codec selftest: malformed table marker was accepted\n"); + failures++; + } + if (rs) + ray_release(rs); + release_any(r); + if (q_connect("127.0.0.1", 70000, "", "", 1) != Q_ERR_SOCKET) { fprintf(stderr, "codec selftest: client accepted out-of-range port\n"); failures++;