[erlang-bugs] function clause in io_lib_fread:fread/4 when running out of input before format

Raimo Niskanen <>
Thu Jul 21 16:52:18 CEST 2011


On Wed, Jul 20, 2011 at 12:11:45PM +0200, Klas Johansson wrote:
> Hi,
> 
> Stumbled upon a bug in io_lib (rather in io_lib_fread) when parsing
> ISO 8601 timestamps.
> 
> Given that I parse something like "2009-10-17T18:37:26Z" but (by
> mistake) leave out the trailing "Z" in the input string I get a
> function clause:
> 
>     1> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009-10-17T18:37:26").
>     ** exception error: no function clause matching
>                         io_lib_fread:fread("Z",[],19,[26,37,18,17,10,2009])
> 
> Same thing if I stop at any of the non-control characters (like a dash
> or colon):
> 
>     2> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009").
>     ** exception error: no function clause matching
>                         io_lib_fread:fread("-~2d-~2dT~2d:~2d:~2dZ",[],4,[2009])
> 
> Minimal (and silly) test case:
> 
>     3> io_lib:fread("Z", "").
>     ** exception error: no function clause matching
>                     io_lib_fread:fread("Z",[],0,[])
> 
> I'd expect something like this:
> 
>     4> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009").
>     {more,"~2d-~2dT~2d:~2d:~2dZ",4,[2009]}
> 
> Should be easy to fix, but I've resorted to using re.erl for now.

I confirm it must be a bug, and I will put this solution
into the daily builds 'dev' branch:
--- a/lib/stdlib/src/io_lib_fread.erl
+++ b/lib/stdlib/src/io_lib_fread.erl
@@ -121,6 +121,14 @@ fread([C|Format], [C|Line], N, Results) ->
     fread(Format, Line, N+1, Results);
 fread([_F|_Format], [_C|_Line], _N, _Results) ->
     fread_error(input);
+fread([_|_]=Format, [], N, Results) ->
+    {more,Format,N,Results};
+fread([_|_], eof, _N, []) ->
+    %% This is at start of format string so no error.
+    eof;
+fread([_|_], eof, _N, _Results) ->
+    %% This is an error as there is no more input.
+    fread_error(input);
 fread([], Line, _N, Results) ->
     {ok,reverse(Results),Line}.

I'll have a look at one other pecularity while I'm at it;
reading using io:fread(F, " X") from an io server that
gives some whitespaces followed by EOF will return
'eof' while I think it should return {error,{fread,input}}.
The same for io:fread(F, " ~d").

I think this is a misinterpeted feature of when being at EOF
an io:fread should immediately return 'eof'.

> 
> 
> Cheers,
> Klas
> _______________________________________________
> erlang-bugs mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-bugs

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


More information about the erlang-bugs mailing list