From 3c7c5b7796eb6514da321b62e330cdb9623bdc89 Mon Sep 17 00:00:00 2001 From: pm-conej Date: Wed, 15 Mar 2017 16:50:15 -0500 Subject: [PATCH] check number input (fixes #22) * Add method to verify string is a number for number format Check that the input string for a number format complies with the JSON number standard. https://tools.ietf.org/html/rfc7159#section-6 --- README.FreeBSD | 2 +- README.md | 2 +- configure.in | 4 +- generic/yajltcl.c | 7 +- generic/yajltcllex.c | 201 ++++++++++++++++++++++++++++++++++++++++++ generic/yajltcllex.h | 16 ++++ generic/yajltcllex.re | 16 ++++ update_ver.sh | 2 +- 8 files changed, 242 insertions(+), 8 deletions(-) mode change 100644 => 100755 README.FreeBSD create mode 100644 generic/yajltcllex.c create mode 100644 generic/yajltcllex.h create mode 100644 generic/yajltcllex.re diff --git a/README.FreeBSD b/README.FreeBSD old mode 100644 new mode 100755 index 9137126..593aa96 --- a/README.FreeBSD +++ b/README.FreeBSD @@ -3,5 +3,5 @@ # autoconf -./configure --with-tcl=/usr/local/lib/tcl8.5 --mandir=/usr/local/man --enable-symbols +./configure --with-tcl=/usr/local/lib/tcl8.6 --mandir=/usr/local/man --enable-symbols diff --git a/README.md b/README.md index 0bff8ed..c23b97d 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ### This is yajl-tcl, a direct Tcl interface to the yajl JSON generator library. -*Version 1.6.1* +*Version 1.6.2* This package is a freely available open source package under the "Berkeley" license, same as Tcl. You can do virtually anything you like with it, such as modifying it, redistributing it, and selling it either in whole or in part. See the file "LICENSE" for complete information. diff --git a/configure.in b/configure.in index 0e21d3c..a5642a5 100755 --- a/configure.in +++ b/configure.in @@ -18,7 +18,7 @@ dnl to configure the system for the local environment. # so you can encode the package version directly into the source files. #----------------------------------------------------------------------- -AC_INIT([yajltcl], [1.6.1]) +AC_INIT([yajltcl], [1.6.2]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. @@ -70,7 +70,7 @@ TEA_SETUP_COMPILER # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- -TEA_ADD_SOURCES([yajltcl.c tclyajltcl.c]) +TEA_ADD_SOURCES([yajltcl.c tclyajltcl.c yajltcllex.c]) TEA_ADD_HEADERS([]) TEA_ADD_INCLUDES([]) TEA_ADD_LIBS([]) diff --git a/generic/yajltcl.c b/generic/yajltcl.c index 3a8400e..e972040 100644 --- a/generic/yajltcl.c +++ b/generic/yajltcl.c @@ -4,6 +4,7 @@ #include #include "yajltcl.h" +#include "yajltcllex.h" #include @@ -827,9 +828,9 @@ yajltcl_yajlObjectObjCmd(ClientData cData, Tcl_Interp *interp, int objc, Tcl_Obj } number = Tcl_GetStringFromObj (objv[++arg], &len); - if (len == 0) { - Tcl_AppendResult(interp, "invalid value \"", number, "\" for number", NULL); - return TCL_ERROR; + if (!numberValidator(number)) { + Tcl_AppendResult(interp, "Invalid value \"", number ,"\" for number input.", NULL); + return TCL_ERROR; } gstatus = yajl_gen_number (hand, number, len); break; diff --git a/generic/yajltcllex.c b/generic/yajltcllex.c new file mode 100644 index 0000000..bc5d12d --- /dev/null +++ b/generic/yajltcllex.c @@ -0,0 +1,201 @@ +/* Generated by re2c 0.16 on Tue Mar 14 22:35:40 2017 */ +#line 1 "yaltcllex.re" +#include +#include "yajltcllex.h" + +/* + * Method: numberValidator + * + * Parameters: + * char *YYCURSOR - Input string buffer + * + * Returns: + * 1 if valid Number + * 0 if invalid Number + * + * This function is generated by re2c from the + * yajltcllex.re file. It is an expression based + * lexer that validates the input conforms to a + * number format as specified by: + * https://tools.ietf.org/html/rfc7159#section-6 + * + * The original regex validation is: + * [-]?([0]|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)? + * + */ +int numberValidator(const char *YYCURSOR) +{ + const char *YYMARKER; + +#line 10 "numberParser.c" +{ + char yych; + yych = *YYCURSOR; + switch (yych) { + case '-': goto yy4; + case '0': goto yy5; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy6; + default: goto yy2; + } +yy2: + ++YYCURSOR; +yy3: +#line 13 "numberParser.re" + { return 0; } +#line 33 "numberParser.c" +yy4: + yych = *(YYMARKER = ++YYCURSOR); + switch (yych) { + case '0': goto yy7; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy9; + default: goto yy3; + } +yy5: + yych = *(YYMARKER = ++YYCURSOR); + switch (yych) { + case 0x00: goto yy11; + case '.': goto yy13; + case 'E': + case 'e': goto yy14; + default: goto yy3; + } +yy6: + yych = *(YYMARKER = ++YYCURSOR); + switch (yych) { + case 0x00: goto yy11; + case '.': goto yy13; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy9; + case 'E': + case 'e': goto yy14; + default: goto yy3; + } +yy7: + yych = *++YYCURSOR; + switch (yych) { + case 0x00: goto yy11; + case '.': goto yy13; + case 'E': + case 'e': goto yy14; + default: goto yy8; + } +yy8: + YYCURSOR = YYMARKER; + goto yy3; +yy9: + ++YYCURSOR; + yych = *YYCURSOR; + switch (yych) { + case 0x00: goto yy11; + case '.': goto yy13; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy9; + case 'E': + case 'e': goto yy14; + default: goto yy8; + } +yy11: + ++YYCURSOR; +#line 14 "numberParser.re" + { return 1; } +#line 113 "numberParser.c" +yy13: + yych = *++YYCURSOR; + switch (yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy15; + default: goto yy8; + } +yy14: + yych = *++YYCURSOR; + switch (yych) { + case 0x00: goto yy8; + case '+': + case '-': goto yy17; + default: goto yy19; + } +yy15: + ++YYCURSOR; + yych = *YYCURSOR; + switch (yych) { + case 0x00: goto yy11; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy15; + case 'E': + case 'e': goto yy14; + default: goto yy8; + } +yy17: + yych = *++YYCURSOR; + if (yych <= 0x00) goto yy8; + goto yy19; +yy18: + ++YYCURSOR; + yych = *YYCURSOR; +yy19: + switch (yych) { + case 0x00: goto yy11; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy18; + default: goto yy8; + } +} +#line 15 "numberParser.re" + +} \ No newline at end of file diff --git a/generic/yajltcllex.h b/generic/yajltcllex.h new file mode 100644 index 0000000..e4c2213 --- /dev/null +++ b/generic/yajltcllex.h @@ -0,0 +1,16 @@ +/* + * + * Include file for yajllex parser + * + * Copyright (C) 2010 by FlightAware, All Rights Reserved + * + * Freely redistributable under the Berkeley copyright, see license.terms + * for details. + */ + +/* + * Validates that the input string is a valid number + */ + +int +numberValidator(const char *YYCURSOR); \ No newline at end of file diff --git a/generic/yajltcllex.re b/generic/yajltcllex.re new file mode 100644 index 0000000..8e11508 --- /dev/null +++ b/generic/yajltcllex.re @@ -0,0 +1,16 @@ +#include + +int numberValidator(const char *YYCURSOR) +{ + const char *YYMARKER; + /*!re2c + re2c:define:YYCTYPE = char; + re2c:yyfill:enable = 0; + + end = "\x00"; + num = [-]?([0]|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?; + + * { return 0; } + num end { return 1; } + */ +} diff --git a/update_ver.sh b/update_ver.sh index 131a013..7bfb5ef 100755 --- a/update_ver.sh +++ b/update_ver.sh @@ -2,7 +2,7 @@ # This script simplifies the process of incrementing all version numbers for a new release. -NEWVER="1.6.1" +NEWVER="1.6.2" perl -p -i -e "s/^(AC_INIT\\(\\[[a-z_]+\\],) \\[[0-9.]+\\]/\\1 \\[$NEWVER\\]/" configure.in