Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

added tests for bad RDS input; also improved the error messages retur…

…ned to the user.
  • Loading branch information...
commit d9b89d6d3ca50e7a1fe59ea2461628203f8aca5d 1 parent 32c8cbc
@agentzh agentzh authored
Showing with 411 additions and 11 deletions.
  1. +13 −10 src/rds_parser.c
  2. +3 −1 t/RdsParser.pm
  3. +395 −0 t/error.t
View
23 src/rds_parser.c
@@ -22,7 +22,7 @@ static int rds_parse_col(lua_State *L, rds_buf_t *b, rds_column_t *col);
static int rds_parse_row(lua_State *L, rds_buf_t *b, rds_header_t *header,
rds_column_t *cols, int row);
static int rds_parse_field(lua_State *L, rds_buf_t *b, rds_header_t *header,
- rds_column_t *cols, int col, int rows);
+ rds_column_t *cols, int col, int row);
static char *rds_null = NULL;
@@ -162,7 +162,7 @@ rds_parse_row(lua_State *L, rds_buf_t *b, rds_header_t *header,
int col;
int rc;
- dd("parsing row %d, top %d", row, lua_gettop(L));
+ dd("parsing row %d, top %d", row + 1, lua_gettop(L));
if (b->last - b->pos < (ssize_t) sizeof(uint8_t)) {
lua_pushnil(L);
@@ -174,8 +174,8 @@ rds_parse_row(lua_State *L, rds_buf_t *b, rds_header_t *header,
if (b->pos != b->last) {
lua_pushnil(L);
lua_pushfstring(L, "seen unexpected leve-over data bytes "
- "at offset %d after parsing %d rows",
- (int) (b->pos - b->start), row);
+ "at offset %d, row %d",
+ (int) (b->pos - b->start), row + 1);
return 2;
}
@@ -205,18 +205,19 @@ rds_parse_row(lua_State *L, rds_buf_t *b, rds_header_t *header,
static int
rds_parse_field(lua_State *L, rds_buf_t *b, rds_header_t *header,
- rds_column_t *cols, int col, int rows)
+ rds_column_t *cols, int col, int row)
{
size_t len;
lua_Number num;
lua_Integer integer;
- dd("parsing field at row %d, col %d, top %d", rows, col, lua_gettop(L));
+ dd("parsing field at row %d, col %d, top %d", row + 1, col + 1,
+ lua_gettop(L));
if (b->last - b->pos < (ssize_t) sizeof(uint32_t)) {
lua_pushnil(L);
lua_pushfstring(L, "field size is incomplete at offset %d, row %d, "
- "col %d", (int) (b->pos - b->start), rows, col);
+ "col %d", (int) (b->pos - b->start), row + 1, col + 1);
return 2;
}
@@ -237,7 +238,7 @@ rds_parse_field(lua_State *L, rds_buf_t *b, rds_header_t *header,
if (b->last - b->pos < (ssize_t) len) {
lua_pushnil(L);
lua_pushfstring(L, "field value is incomplete at offset %d, row %d,"
- " col %d", (int) (b->pos - b->start), rows, col);
+ " col %d", (int) (b->pos - b->start), row + 1, col + 1);
return 2;
}
@@ -271,7 +272,8 @@ rds_parse_field(lua_State *L, rds_buf_t *b, rds_header_t *header,
lua_pushnil(L);
lua_pushfstring(L, "unrecognized boolean value at offset %d, "
- "row %d, col %d", (int) (b->pos - b->start), rows, col);
+ "row %d, col %d", (int) (b->pos - b->start), row + 1,
+ col + 1);
return 2;
default:
@@ -336,7 +338,8 @@ rds_parse_header(lua_State *L, rds_buf_t *b, rds_header_t *header)
if (*b->pos != 0) {
lua_pushnil(L);
- lua_pushliteral(L, "rds: RDS result type must be 0 for now");
+ lua_pushfstring(L, "RDS result type must be 0 for now but got %d",
+ (int) *b->pos);
return 2;
}
View
4 t/RdsParser.pm
@@ -42,7 +42,9 @@ f:close()
local parser = require "rds.parser"
local res, err = parser.parse(rds)
if res == nil then
- error("failed to parse: " .. err)
+ print(res)
+ print(err)
+ return
end
local cjson = require "cjson"
print(cjson.encode(res))
View
395 t/error.t
@@ -0,0 +1,395 @@
+# vi:ft=
+
+use strict;
+use warnings;
+
+use t::RdsParser;
+plan tests => 1 * blocks();
+
+#no_long_string();
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: truncate at row terminator
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{02}\x{00}". # col count
+"\x{09}\x{00}". # std col type (integer)
+"\x{03}\x{00}". # drizzle col type
+"\x{02}\x{00}". # col name len
+"id". # col name data
+"\x{13}\x{80}". # std col type (blob/str)
+"\x{fc}\x{00}". # drizzle col type
+"\x{04}\x{00}". # col name len
+"name". # col name data
+"\x{01}". # valid row flag
+"\x{01}\x{00}\x{00}\x{00}". # field len
+"2". # field data
+"\x{ff}\x{ff}\x{ff}\x{ff}". # field len
+"". # field data
+"\x{01}". # valid row flag
+"\x{01}\x{00}\x{00}\x{00}". # field len
+"3". # field data
+"\x{03}\x{00}\x{00}\x{00}". # field len
+"bob" # field data
+--- out
+nil
+row flag is incomplete
+
+
+
+=== TEST 2: truncate at field data
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{02}\x{00}". # col count
+"\x{09}\x{00}". # std col type (integer)
+"\x{03}\x{00}". # drizzle col type
+"\x{02}\x{00}". # col name len
+"id". # col name data
+"\x{13}\x{80}". # std col type (blob/str)
+"\x{fc}\x{00}". # drizzle col type
+"\x{04}\x{00}". # col name len
+"name". # col name data
+"\x{01}". # valid row flag
+"\x{01}\x{00}\x{00}\x{00}". # field len
+"2". # field data
+"\x{ff}\x{ff}\x{ff}\x{ff}". # field len
+"". # field data
+"\x{01}". # valid row flag
+"\x{01}\x{00}\x{00}\x{00}". # field len
+"3". # field data
+"\x{03}\x{00}\x{00}\x{00}". # field len
+"bo" # field data
+--- out
+nil
+field value is incomplete at offset 68, row 2, col 2
+
+
+
+=== TEST 3: truncate at field len
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{02}\x{00}". # col count
+"\x{09}\x{00}". # std col type (integer)
+"\x{03}\x{00}". # drizzle col type
+"\x{02}\x{00}". # col name len
+"id". # col name data
+"\x{13}\x{80}". # std col type (blob/str)
+"\x{fc}\x{00}". # drizzle col type
+"\x{04}\x{00}". # col name len
+"name". # col name data
+"\x{01}". # valid row flag
+"\x{01}\x{00}\x{00}\x{00}". # field len
+"2". # field data
+"\x{ff}\x{ff}\x{ff}\x{ff}". # field len
+"". # field data
+"\x{01}". # valid row flag
+"\x{01}\x{00}\x{00}\x{00}". # field len
+"3". # field data
+"\x{03}\x{00}\x{00}" # field len
+--- out
+nil
+field size is incomplete at offset 64, row 2, col 2
+
+
+
+=== TEST 4: truncate at field len (a different cell)
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{02}\x{00}". # col count
+"\x{09}\x{00}". # std col type (integer)
+"\x{03}\x{00}". # drizzle col type
+"\x{02}\x{00}". # col name len
+"id". # col name data
+"\x{13}\x{80}". # std col type (blob/str)
+"\x{fc}\x{00}". # drizzle col type
+"\x{04}\x{00}". # col name len
+"name". # col name data
+"\x{01}". # valid row flag
+"\x{01}\x{00}\x{00}" # field len
+--- out
+nil
+field size is incomplete at offset 49, row 1, col 1
+
+
+
+=== TEST 5: truncate at field len
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{02}\x{00}". # col count
+"\x{09}\x{00}". # std col type (integer)
+"\x{03}\x{00}". # drizzle col type
+"\x{02}\x{00}". # col name len
+"id". # col name data
+"\x{13}\x{80}". # std col type (blob/str)
+"\x{fc}\x{00}". # drizzle col type
+"\x{04}\x{00}". # col name len
+"name". # col name data
+"\x{01}". # valid row flag
+"\x{01}\x{00}\x{00}\x{00}". # field len
+"2". # field data
+"\x{ff}\x{ff}\x{ff}\x{ff}". # field len
+"". # field data
+"\x{01}" # valid row flag
+--- out
+nil
+field size is incomplete at offset 59, row 2, col 1
+
+
+
+=== TEST 6: truncate at col name data
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{02}\x{00}". # col count
+"\x{09}\x{00}". # std col type (integer)
+"\x{03}\x{00}". # drizzle col type
+"\x{02}\x{00}". # col name len
+"id". # col name data
+"\x{13}\x{80}". # std col type (blob/str)
+"\x{fc}\x{00}". # drizzle col type
+"\x{04}\x{00}". # col name len
+"nam" # col name data
+--- out
+nil
+column name string is incomplete
+
+
+
+=== TEST 7: truncate at col name len
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{02}\x{00}". # col count
+"\x{09}\x{00}". # std col type (integer)
+"\x{03}\x{00}". # drizzle col type
+"\x{02}\x{00}". # col name len
+"id". # col name data
+"\x{13}\x{80}". # std col type (blob/str)
+"\x{fc}\x{00}". # drizzle col type
+"\x{04}" # col name len
+--- out
+nil
+column spec is incomplete
+
+
+
+=== TEST 8: truncate at col type
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{02}\x{00}". # col count
+"\x{09}\x{00}". # std col type (integer)
+"\x{03}\x{00}". # drizzle col type
+"\x{02}\x{00}". # col name len
+"id". # col name data
+"\x{13}\x{80}". # std col type (blob/str)
+"\x{fc}" # drizzle col type
+--- out
+nil
+column spec is incomplete
+
+
+
+=== TEST 9: truncate at col count
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{02}" # col count
+--- out
+nil
+header part is incomplete
+
+
+
+=== TEST 10: truncate at insert id
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}" # insert id
+--- out
+nil
+header part is incomplete
+
+
+
+=== TEST 11: truncate at rows affected
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{00}\x{00}". # driver errstr len
+"". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}" # rows affected
+--- out
+nil
+header part is incomplete
+
+
+
+=== TEST 12: truncate at errstr data
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{03}\x{00}". # driver errstr len
+"he" # driver errstr data
+--- out
+nil
+header part is incomplete
+
+
+
+=== TEST 13: truncate at errstr len
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{03}" # driver errstr len
+--- out
+nil
+header part is incomplete
+
+
+
+=== TEST 14: truncate at driver errcode
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}" # driver errcode
+--- out
+nil
+header part is incomplete
+
+
+
+=== TEST 15: truncate at std errcode
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{00}". # result type
+"\x{00}" # std errcode
+--- out
+nil
+header part is incomplete
+
+
+
+=== TEST 16: bad result type
+--- rds eval
+"\x{00}". # endian
+"\x{03}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{03}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{28}\x{00}". # driver errstr len
+"Rows matched: 1 Changed: 0 Warnings: 0". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{00}\x{00}" # col count
+--- out
+nil
+RDS result type must be 0 for now but got 3
+
+
+
+=== TEST 17: bad format version
+--- rds eval
+"\x{00}". # endian
+"\x{01}\x{00}\x{00}\x{00}". # format version 0.0.3
+"\x{03}". # result type
+"\x{00}\x{00}". # std errcode
+"\x{00}\x{00}" . # driver errcode
+"\x{28}\x{00}". # driver errstr len
+"Rows matched: 1 Changed: 0 Warnings: 0". # driver errstr data
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # rows affected
+"\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}\x{00}". # insert id
+"\x{00}\x{00}" # col count
+--- out
+nil
+found RDS format version 1, but we can only handle version 3
+
Please sign in to comment.
Something went wrong with that request. Please try again.