Affected: urweb.lex

1. Oversized int literals throw an unhandled Overflow exception in SML Basis Int64.fromString, making the lexer fail.

Documentation: http://sml-family.org/Basis/integer.html#SIG:INTEGER.scan:VAL

Adding

handle Overflow => NONE

solves it.

2. Hexadecimal literals are defined too shortly, and refuse values bigger then 32 bits.

hexconst = 0x[0-9A-F]{1,8};

The actual definition with max. repetitions specifier, causes an oversized literal to be split in two tokens making the error ugly.

It is better to accept the whole token and check for the Overflow when converted, adding the exception handler as with the previous section.

(This bug is from a proposal of mine, so It was my fault)




--- ../../urweb-20150520/src/urweb.lex	2015-04-12 20:22:03.000000000 +0200
+++ urweb-20150520/src/urweb.lex	2015-05-26 13:08:07.509897000 +0200
@@ -182,7 +182,7 @@
 ws = [\ \t\012\r];
 intconst = [0-9]+;
 realconst = [0-9]+\.[0-9]*;
-hexconst = 0x[0-9A-F]{1,8};
+hexconst = 0x[0-9A-F]+;
 notags = ([^<{\n(]|(\([^\*<{\n]))+;
 xcom = ([^\-]|(-[^\-]))+;
 oint = [0-9][0-9][0-9];
@@ -542,17 +542,25 @@
 <INITIAL> {id}        => (Tokens.SYMBOL (yytext, pos yypos, pos yypos + size yytext));
 <INITIAL> {cid}       => (Tokens.CSYMBOL (yytext, pos yypos, pos yypos + size yytext));
 
-<INITIAL> {hexconst}  => (case StringCvt.scanString (Int64.scan StringCvt.HEX) (String.extract (yytext, 2, NONE)) of
+<INITIAL> {hexconst}  => (let val digits = String.extract (yytext, 2, NONE) ;
+                              val v = (StringCvt.scanString (Int64.scan StringCvt.HEX) digits)
+                                      handle Overflow => NONE
+                          in
+                          case v of
                               SOME x => Tokens.INT (x, pos yypos, pos yypos + size yytext)
                             | NONE   => (ErrorMsg.errorAt' (pos yypos, pos yypos)
                                                            ("Expected hexInt, received: " ^ yytext);
-                                         continue ()));
+                                         continue ())
+                         end);
 
-<INITIAL> {intconst}  => (case Int64.fromString yytext of
+<INITIAL> {intconst}  => (let val v = (Int64.fromString yytext) handle Overflow => NONE
+                          in 
+                          case v of
                               SOME x => Tokens.INT (x, pos yypos, pos yypos + size yytext)
                             | NONE   => (ErrorMsg.errorAt' (pos yypos, pos yypos)
                                                            ("Expected int, received: " ^ yytext);
-                                         continue ()));
+                                         continue ())
+                         end);
 <INITIAL> {realconst} => (case Real64.fromString yytext of
                             SOME x => Tokens.FLOAT (x, pos yypos, pos yypos + size yytext)
                           | NONE   => (ErrorMsg.errorAt' (pos yypos, pos yypos)

_______________________________________________
Ur mailing list
[email protected]
http://www.impredicative.com/cgi-bin/mailman/listinfo/ur

Reply via email to