# HG changeset patch # User Philip Nienhuis # Date 1407958193 -7200 # Node ID c573d9c70ae54987ddc149477cd7fc7129929496 # Parent ec28b721650116ea26e05216056520d2f340eab9 Better checks for valid format conversion specifiers in textscan. & strread.m * textscan.m: more rigid format conversion specifier check & test added * strread.m: more rigid format conversion specifier check & test added more to-the-point error messages diff -r ec28b7216501 -r c573d9c70ae5 scripts/io/strread.m --- a/scripts/io/strread.m Sun Aug 24 15:25:21 2014 -0700 +++ b/scripts/io/strread.m Wed Aug 13 21:29:53 2014 +0200 @@ -197,10 +197,12 @@ endif ## Parse format string to compare number of conversion fields and nargout - nfields = length (strfind (format, "%")) - length (strfind (format, "%*")); + nfields = numel (regexp (format, '(%(\d*|\d*\.\d*)?[nfduscq]|%\[)', "match")); ## If str only has numeric fields, a (default) format ("%f") will do. ## Otherwise: - if ((max (nargout, 1) != nfields) && ! strcmp (format, "%f")) + if (! nfields) + error ("strread.m: no valid format conversion specifiers found\n"); + elseif ((max (nargout, 1) != nfields) && ! strcmp (format, "%f")) error ("strread: the number of output variables must match that specified by FORMAT"); endif @@ -304,7 +306,8 @@ fmt_words = regexp (format, '[^ ]+', "match"); ## Find position of conversion specifiers (they start with %) - idy2 = find (! cellfun ("isempty", regexp (fmt_words, '^%'))); + fcs_ptrn = '(%\*?(\d*|\d*\.\d*)?[nfduscq]|%\*?\[)'; + idy2 = find (! cellfun ("isempty", regexp (fmt_words, fcs_ptrn))); ## Check for unsupported format specifiers errpat = '(\[.*\]|[cq]|[nfdu]8|[nfdu]16|[nfdu]32|[nfdu]64)'; @@ -1034,5 +1037,8 @@ %% Illegal format specifiers %!test -%!error strread ("1.0", "%z") +%!error strread ("1.0", "%z"); +%% Test for false positives in check for non-supported format specifiers +%!test +%! assert (strread ("Total: 32.5 % (of cm values)","Total: %f % (of cm values)"), 32.5, 1e-5); diff -r ec28b7216501 -r c573d9c70ae5 scripts/io/textscan.m --- a/scripts/io/textscan.m Sun Aug 24 15:25:21 2014 -0700 +++ b/scripts/io/textscan.m Wed Aug 13 21:29:53 2014 +0200 @@ -98,7 +98,10 @@ endif ## Determine the number of data fields & initialize output array - num_fields = numel (strfind (format, "%")) - numel (strfind (format, "%*")); + num_fields = numel (regexp (format, '(%(\d*|\d*\.\d*)?[nfduscq]|%\[)', "match")); + if (! num_fields) + error ("textscan.m: no valid format conversion specifiers found\n"); + endif C = cell (1, num_fields); if (! (isa (fid, "double") && fid > 0) && ! ischar (fid)) @@ -681,3 +684,7 @@ %!test %! assert (textscan ("1i", ""){1}, 0+1i); %! assert (cell2mat (textscan ("3, 2-4i, NaN\n -i, 1, 23.4+2.2i", "")), [3+0i, 2-4i, NaN+0i; 0-i, 1+0i, 23.4+2.2i]); + +%% Illegal format specifiers +%!test +%!error textscan ("1.0", "%z");