changeset 19437:03067dab10ca

Use stricter input validation when looking for a string as input (bug #42651). * data.cc (get_sort_mode_option, Fissorted): Use is_string() to check string input. * debug.cc (Fdbstep): use "string" rather than "character string" in error messages. * error.cc (Flasterr, Flastwarn): use "string" rather than "character string" in error messages. * file-io.cc (do_stream_open, do_fread, do_fwrite, Fpopen, Ftempname, Fmkstemp): Use is_string() to check string input. * graphics.cc (Fgraphics_toolkit): Use is_string() to check string input. Rephrase error message. * help.cc (F__list_functions): Use is_string() to check string input. * input.cc (Fyes_or_no): Use is_string() to check string input. Rephrase error message. * input.cc (Fadd_input_event_hook): Rephrase error message. * load-path.cc (Fgenpath, Faddpath): Rephrase error message. * matrix_type.cc (Fmatrix_type): Use is_string() to check string input. * qz.cc (Fqz): Follow Octave coding convention for space after '!'. * regexp.cc (parse_options): Use is_string() to check string input. Rephrase error message. * schur.cc (Fschur): Use is_string() to check string input. * strfns.cc (Flist_in_columns): Use is_string() to check string input. Rephrase error message. * symtab.cc (Fignore_function_time_stamp): Use is_string() to check string input. Rephrase error message. * syscalls.cc (Fexec, Fpopen2, Fcanonicalize_file_name): Use is_string() to check string input. Rephrase error message. * sysdep.cc (Fsetenv): Use is_string() to check string input. * time.cc (Fstrftime, Fstrptime): Use is_string() to check string input. * toplev.cc (Fsystem, Fatexit): Use is_string() to check string input. * urlwrite.cc (Furlwrite, Furlread): Rephrase error message. * utils.cc (Ffile_in_path): Use is_string() to check string input. Rephrase error message. * variables.cc (extract_function): Add FIXME about potentially using is_string. * variables.cc (do_isglobal, Fmunlock, Fmislocked): Use is_string() to check string input. * variables.cc (set_internal_variable): Rephrase error message. * ov-base.cc (make_idx_args): Rephrase error message. * ov-class.cc (octave_class::all_strings, Fclass): Rephrase error message. * ov-fcn-handle.cc (Fstr2func): Use is_string() to check string input * ov-java.cc (FjavaObject, FjavaMethod, F__java_get__, F__java_set__): Use is_string() to check string input. * ov.cc (Fdecode_subscripts): Use is_string() to check string input. Rephrase error message. * pt-idx.cc (tree_index_expression::get_struct_index): Rephrase error message. * io.tst: Change %!warning test to %!error test to match stricter checking. * system.tst: Change %!warning test for setenv to %!error test to match stricter checking.
author Rik <rik@octave.org>
date Tue, 16 Dec 2014 09:21:29 -0800
parents 5cd83b466a3e
children c2f4f6eb5907
files libinterp/corefcn/data.cc libinterp/corefcn/debug.cc libinterp/corefcn/error.cc libinterp/corefcn/file-io.cc libinterp/corefcn/graphics.cc libinterp/corefcn/help.cc libinterp/corefcn/input.cc libinterp/corefcn/load-path.cc libinterp/corefcn/matrix_type.cc libinterp/corefcn/qz.cc libinterp/corefcn/regexp.cc libinterp/corefcn/schur.cc libinterp/corefcn/strfns.cc libinterp/corefcn/symtab.cc libinterp/corefcn/syscalls.cc libinterp/corefcn/sysdep.cc libinterp/corefcn/time.cc libinterp/corefcn/toplev.cc libinterp/corefcn/urlwrite.cc libinterp/corefcn/utils.cc libinterp/corefcn/variables.cc libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-class.cc libinterp/octave-value/ov-fcn-handle.cc libinterp/octave-value/ov-java.cc libinterp/octave-value/ov.cc libinterp/parse-tree/pt-idx.cc test/io.tst test/system.tst
diffstat 29 files changed, 209 insertions(+), 220 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/data.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/data.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -6855,18 +6855,20 @@
   // FIXME: shouldn't these modes be scoped inside a class?
   sortmode smode = UNSORTED;
 
-  std::string mode = arg.string_value ();
-
-  if (error_state)
-    error ("issorted: expecting %s argument to be a character string", argn);
-  else if (mode == "ascending")
-    smode = ASCENDING;
-  else if (mode == "descending")
-    smode = DESCENDING;
-  else if (mode == "either")
-    smode = UNSORTED;
+  if (arg.is_string ())
+    {
+      std::string mode = arg.string_value ();
+      if (mode == "ascending")
+        smode = ASCENDING;
+      else if (mode == "descending")
+        smode = DESCENDING;
+      else if (mode == "either")
+        smode = UNSORTED;
+      else
+        error ("issorted: MODE must be \"ascending\", \"descending\", or \"either\"");
+    }
   else
-    error ("issorted: MODE must be \"ascending\", \"descending\", or \"either\"");
+    error ("issorted: expecting %s argument to be a string", argn);
 
   return smode;
 }
@@ -6910,17 +6912,16 @@
       if (nargin == 3)
         smode = get_sort_mode_option (args(2), "third");
 
-      std::string tmp = args(1).string_value ();
-
-      if (! error_state)
+      if (args(1).is_string ())
         {
+          std::string tmp = args(1).string_value ();
           if (tmp == "rows")
             by_rows = true;
           else
             smode = get_sort_mode_option (args(1), "second");
         }
       else
-        error ("expecting second argument to be character string");
+        error ("issorted: second argument must be a string");
 
       if (error_state)
         return retval;
--- a/libinterp/corefcn/debug.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/debug.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -1462,7 +1462,7 @@
                 }
             }
           else
-            error ("dbstep: input argument must be a character string");
+            error ("dbstep: input argument must be a string");
         }
       else
         {
--- a/libinterp/corefcn/error.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/error.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -1866,7 +1866,7 @@
             }
         }
       else
-        error ("lasterr: expecting arguments to be character strings");
+        error ("lasterr: all arguments must be strings");
     }
   else
     print_usage ();
@@ -1913,7 +1913,7 @@
             }
         }
       else
-        error ("lastwarn: expecting arguments to be character strings");
+        error ("lastwarn: all arguments must be strings");
     }
   else
     print_usage ();
--- a/libinterp/corefcn/file-io.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/file-io.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -557,18 +557,20 @@
 
   fid = -1;
 
-  std::string name = tc_name.string_value ();
-
-  if (! error_state)
+  if (tc_name.is_string ())
     {
-      std::string mode = tc_mode.string_value ();
+      std::string name = tc_name.string_value ();
 
-      if (! error_state)
+      if (tc_mode.is_string ())
         {
-          std::string arch = tc_arch.string_value ();
+          std::string mode = tc_mode.string_value ();
 
-          if (! error_state)
-            retval = do_stream_open (name, mode, arch, fid);
+          if (tc_arch.is_string ())
+            {
+              std::string arch = tc_arch.string_value ();
+
+              retval = do_stream_open (name, mode, arch, fid);
+            }
           else
             ::error ("%s: architecture type must be a string", fcn);
         }
@@ -1371,10 +1373,10 @@
 
   if (! error_state)
     {
-      std::string prec = prec_arg.string_value ();
+      if (prec_arg.is_string ())
+        {
+          std::string prec = prec_arg.string_value ();
 
-      if (! error_state)
-        {
           int block_size = 1;
           oct_data_conv::data_type input_type;
           oct_data_conv::data_type output_type;
@@ -1388,10 +1390,10 @@
 
               if (! error_state)
                 {
-                  std::string arch = arch_arg.string_value ();
+                  if (arch_arg.is_string ())
+                    {
+                      std::string arch = arch_arg.string_value ();
 
-                  if (! error_state)
-                    {
                       oct_mach_info::float_format flt_fmt
                         = oct_mach_info::string_to_float_format (arch);
 
@@ -1641,10 +1643,10 @@
 {
   int retval = -1;
 
-  std::string prec = prec_arg.string_value ();
+  if (prec_arg.is_string ())
+    {
+      std::string prec = prec_arg.string_value ();
 
-  if (! error_state)
-    {
       int block_size = 1;
       oct_data_conv::data_type output_type;
 
@@ -1656,10 +1658,10 @@
 
           if (! error_state)
             {
-              std::string arch = arch_arg.string_value ();
+              if (arch_arg.is_string ())
+                {
+                  std::string arch = arch_arg.string_value ();
 
-              if (! error_state)
-                {
                   oct_mach_info::float_format flt_fmt
                     = oct_mach_info::string_to_float_format (arch);
 
@@ -1874,14 +1876,14 @@
 
   if (nargin == 2)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
-          std::string mode = args(1).string_value ();
+          std::string name = args(0).string_value ();
 
-          if (! error_state)
+          if (args(1).is_string ())
             {
+              std::string mode = args(1).string_value ();
+
               if (mode == "r")
                 {
                   octave_stream ips = octave_iprocstream::create (name);
@@ -1955,20 +1957,25 @@
 
   if (len < 3)
     {
-      std::string dir = len > 0 ? args(0).string_value () : std::string ();
-
-      if (! error_state)
+      std::string dir;
+      if (len > 0)
         {
-          std::string pfx
-            = len > 1 ? args(1).string_value () : std::string ("oct-");
+          if (args(0).is_string ())
+            dir = args(0).string_value ();
+          else
+            ::error ("DIR must be a string");
+        }
 
-          if (! error_state)
-            retval = octave_tempnam (dir, pfx);
+      std::string pfx ("oct-");
+      if (len > 1)
+        {
+          if (args(1).is_string ())
+            pfx = args(1).string_value ();
           else
             ::error ("PREFIX must be a string");
         }
-      else
-        ::error ("DIR argument must be a string");
+
+      retval = octave_tempnam (dir, pfx);
     }
   else
     print_usage ();
@@ -2061,10 +2068,10 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      std::string tmpl8 = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string tmpl8 = args(0).string_value ();
 
-      if (! error_state)
-        {
           OCTAVE_LOCAL_BUFFER (char, tmp, tmpl8.size () + 1);
           strcpy (tmp, tmpl8.c_str ());
 
--- a/libinterp/corefcn/graphics.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/graphics.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -10746,12 +10746,13 @@
 
   if (args.length () == 1)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
-        gtk_manager::register_toolkit (name);
+      if (args(0).is_string ())
+        {
+          std::string name = args(0).string_value ();
+          gtk_manager::register_toolkit (name);
+        }
       else
-        error ("register_graphics_toolkit: expecting character string");
+        error ("register_graphics_toolkit: TOOLKIT must be a string");
     }
   else
     print_usage ();
--- a/libinterp/corefcn/help.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/help.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -1366,27 +1366,24 @@
 
   if (args.length () == 0)
     retval = Cell (ffl.append (afl));
-  else
+  else if (args(0).is_string ())
     {
       std::string dir = args(0).string_value ();
 
+      string_vector fl = load_path::files (dir, true);
+
       if (! error_state)
         {
-          string_vector fl = load_path::files (dir, true);
+          // Return a sorted list with unique entries (in case of
+          // .m and .oct versions of the same function in a given
+          // directory, for example).
+          fl.sort (true);
 
-          if (! error_state)
-            {
-              // Return a sorted list with unique entries (in case of
-              // .m and .oct versions of the same function in a given
-              // directory, for example).
-              fl.sort (true);
-
-              retval = Cell (fl);
-            }
+          retval = Cell (fl);
         }
-      else
-        error ("__list_functions__: DIRECTORY argument must be a string");
     }
+  else
+    error ("__list_functions__: DIRECTORY argument must be a string");
 
   return retval;
 }
--- a/libinterp/corefcn/input.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/input.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -837,11 +837,11 @@
 
       if (nargin == 1)
         {
-          prompt = args(0).string_value ();
-
-          if (error_state)
+          if (args(0).is_string ())
+            prompt = args(0).string_value ();
+          else
             {
-              error ("yes_or_no: PROMPT must be a character string");
+              error ("yes_or_no: PROMPT must be a string");
               return retval;
             }
         }
@@ -1210,7 +1210,7 @@
           retval = hook_fcn.id ();
         }
       else
-        error ("add_input_event_hook: expecting function handle or character string as first argument");
+        error ("add_input_event_hook: FCN must be a function handle or string");
     }
   else
     print_usage ();
--- a/libinterp/corefcn/load-path.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/load-path.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -2213,7 +2213,7 @@
       if (! error_state)
         retval = genpath (dirname);
       else
-        error ("genpath: DIR must be a character string");
+        error ("genpath: DIR must be a string");
     }
   else if (nargin > 1)
     {
@@ -2232,7 +2232,7 @@
       if (! error_state)
         retval = genpath (dirname, skip);
       else
-        error ("genpath: all arguments must be character strings");
+        error ("genpath: all arguments must be strings");
     }
   else
     print_usage ();
@@ -2464,7 +2464,7 @@
                 }
             }
           else
-            error ("addpath: all arguments must be character strings");
+            error ("addpath: all arguments must be strings");
         }
 
       if (need_to_update)
@@ -2528,7 +2528,7 @@
                 }
             }
           else
-            error ("addpath: all arguments must be character strings");
+            error ("addpath: all arguments must be strings");
         }
 
       if (need_to_update)
--- a/libinterp/corefcn/matrix_type.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/matrix_type.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -213,18 +213,18 @@
           else
             {
               // Ok, we're changing the matrix type
-              std::string str_typ = args(1).string_value ();
-
-              // FIXME: why do I have to explicitly call the constructor?
-              MatrixType mattyp = MatrixType ();
-
-              octave_idx_type nl = 0;
-              octave_idx_type nu = 0;
-
-              if (error_state)
+              if (! args(1).is_string ())
                 error ("matrix_type: TYPE must be a string");
               else
                 {
+                  std::string str_typ = args(1).string_value ();
+
+                  // FIXME: why do I have to explicitly call the constructor?
+                  MatrixType mattyp = MatrixType ();
+
+                  octave_idx_type nl = 0;
+                  octave_idx_type nu = 0;
+
                   // Use STL function to convert to lower case
                   std::transform (str_typ.begin (), str_typ.end (),
                                   str_typ.begin (), tolower);
@@ -416,15 +416,15 @@
           else
             {
               // Ok, we're changing the matrix type
-              std::string str_typ = args(1).string_value ();
-
-              // FIXME: why do I have to explicitly call the constructor?
-              MatrixType mattyp = MatrixType (MatrixType::Unknown, true);
-
-              if (error_state)
+              if (! args(1).is_string ())
                 error ("matrix_type: TYPE must be a string");
               else
                 {
+                  std::string str_typ = args(1).string_value ();
+
+                  // FIXME: why do I have to explicitly call the constructor?
+                  MatrixType mattyp = MatrixType (MatrixType::Unknown, true);
+
                   // Use STL function to convert to lower case
                   std::transform (str_typ.begin (), str_typ.end (),
                                   str_typ.begin (), tolower);
--- a/libinterp/corefcn/qz.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/qz.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -402,7 +402,7 @@
 
   if (nargin == 2)
     ord_job = 'N';
-  else if (!args(2).is_string ())
+  else if (! args(2).is_string ())
     {
       error ("qz: OPT must be a string");
       return retval;
--- a/libinterp/corefcn/regexp.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/regexp.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -189,12 +189,13 @@
 
   for (int i = skip; i < nargin; i++)
     {
-      std::string str = args(i).string_value ();
+      std::string str;
 
-      if (error_state)
+      if (args(i).is_string ())
+        str = args(i).string_value ();
+      else
         {
-          error ("%s: optional arguments must be character strings",
-                 who.c_str ());
+          error ("%s: optional arguments must be strings", who.c_str ());
           break;
         }
 
--- a/libinterp/corefcn/schur.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/schur.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -143,9 +143,9 @@
 
   if (nargin == 2)
     {
-      ord = args(1).string_value ();
-
-      if (error_state)
+      if (args(1).is_string ())
+        ord = args(1).string_value ();
+      else
         {
           error ("schur: second argument must be a string");
           return retval;
--- a/libinterp/corefcn/strfns.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/strfns.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -916,7 +916,7 @@
 
   if (error_state)
     {
-      error ("list_in_columns: expecting cellstr or char array");
+      error ("list_in_columns: ARG must be a cellstr or char array");
       return retval;
     }
 
@@ -938,18 +938,10 @@
   if (nargin > 2)
     {
       if (args(2).is_string ())
-        {
-          prefix = args(2).string_value ();
-
-          if (error_state)
-            {
-              error ("list_in_columns: PREFIX must be a character string");
-              return retval;
-            }
-        }
+        prefix = args(2).string_value ();
       else
         {
-          error ("list_in_columns: PREFIX must be a character string");
+          error ("list_in_columns: PREFIX must be a string");
           return retval;
         }
     }
--- a/libinterp/corefcn/symtab.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/symtab.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -1676,10 +1676,9 @@
 
   if (nargin == 1)
     {
-      std::string sval = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
+          std::string sval = args(0).string_value ();
           if (sval == "all")
             Vignore_function_time_stamp = 2;
           else if (sval == "system")
@@ -1687,7 +1686,7 @@
           else if (sval == "none")
             Vignore_function_time_stamp = 0;
           else
-            error ("ignore_function_time_stamp: expecting argument to be \"all\", \"system\", or \"none\"");
+            error ("ignore_function_time_stamp: argument must be \"all\", \"system\", or \"none\"");
         }
       else
         error ("ignore_function_time_stamp: expecting argument to be character string");
--- a/libinterp/corefcn/syscalls.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/syscalls.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -190,10 +190,10 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      std::string exec_file = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string exec_file = args(0).string_value ();
 
-      if (! error_state)
-        {
           string_vector exec_args;
 
           if (nargin == 2)
@@ -212,7 +212,7 @@
                     exec_args[i+1] = tmp[i];
                 }
               else
-                error ("exec: arguments must be character strings");
+                error ("exec: all arguments must be strings");
             }
           else
             {
@@ -300,10 +300,10 @@
 
   if (nargin >= 1 && nargin <= 3)
     {
-      std::string exec_file = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string exec_file = args(0).string_value ();
 
-      if (! error_state)
-        {
           string_vector arg_list;
 
           if (nargin >= 2)
@@ -322,7 +322,7 @@
                     arg_list[i+1] = tmp[i];
                 }
               else
-                error ("popen2: arguments must be character strings");
+                error ("popen2: all arguments must be strings");
             }
           else
             {
@@ -367,7 +367,7 @@
                 }
             }
           else
-            error ("popen2: arguments must be character strings");
+            error ("popen2: all arguments must be strings");
         }
       else
         error ("popen2: COMMAND argument must be a string");
@@ -1625,10 +1625,9 @@
 
   if (args.length () == 1)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
+          std::string name = args(0).string_value ();
           std::string msg;
 
           std::string result = octave_canonicalize_file_name (name, msg);
@@ -1638,7 +1637,7 @@
           retval(0) = result;
         }
       else
-        error ("canonicalize_file_name: NAME must be a character string");
+        error ("canonicalize_file_name: NAME must be a string");
     }
   else
     print_usage ();
--- a/libinterp/corefcn/sysdep.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/sysdep.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -636,10 +636,10 @@
 
   if (nargin == 2 || nargin == 1)
     {
-      std::string var = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string var = args(0).string_value ();
 
-      if (! error_state)
-        {
           std::string val = (nargin == 2
                              ? args(1).string_value () : std::string ());
 
--- a/libinterp/corefcn/time.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/time.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -463,10 +463,10 @@
 
   if (args.length () == 2)
     {
-      std::string fmt = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string fmt = args(0).string_value ();
 
-      if (! error_state)
-        {
           octave_scalar_map map = args(1).scalar_map_value ();
 
           if (! error_state)
@@ -519,14 +519,14 @@
 
   if (args.length () == 2)
     {
-      std::string str = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
-          std::string fmt = args(1).string_value ();
+          std::string str = args(0).string_value ();
 
-          if (! error_state)
+          if (args(1).is_string ())
             {
+              std::string fmt = args(1).string_value ();
+
               octave_strptime t (str, fmt);
 
               retval(1) = t.characters_converted ();
--- a/libinterp/corefcn/toplev.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/toplev.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -1006,10 +1006,10 @@
 
       if (nargin == 3)
         {
-          std::string type_str = args(2).string_value ();
+          if (args(2).is_string ())
+            {
+              std::string type_str = args(2).string_value ();
 
-          if (! error_state)
-            {
               if (type_str == "sync")
                 type = et_sync;
               else if (type_str == "async")
@@ -1022,7 +1022,7 @@
             }
           else
             {
-              error ("system: TYPE must be a character string");
+              error ("system: TYPE must be a string");
               return retval;
             }
         }
@@ -1205,10 +1205,10 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      std::string arg = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string arg = args(0).string_value ();
 
-      if (! error_state)
-        {
           bool add_mode = true;
 
           if (nargin == 2)
--- a/libinterp/corefcn/urlwrite.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/urlwrite.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -350,16 +350,17 @@
 
   if (error_state)
     {
-      error ("urlwrite: URL must be a character string");
+      error ("urlwrite: URL must be a string");
       return retval;
     }
 
   // name to store the file if download is succesful
+  // FIXME: Maybe use is_string () for better input validation.
   std::string filename = args(1).string_value ();
 
   if (error_state)
     {
-      error ("urlwrite: LOCALFILE must be a character string");
+      error ("urlwrite: LOCALFILE must be a string");
       return retval;
     }
 
@@ -370,13 +371,7 @@
     {
       method = args(2).string_value ();
 
-      if (error_state)
-        {
-          error ("urlwrite: METHOD must be \"get\" or \"post\"");
-          return retval;
-        }
-
-      if (method != "get" && method != "post")
+      if (error_state || (method != "get" && method != "post"))
         {
           error ("urlwrite: METHOD must be \"get\" or \"post\"");
           return retval;
@@ -386,11 +381,10 @@
 
       if (error_state)
         {
-          error ("urlwrite: parameters (PARAM) for get and post requests must be given as a cell array of character strings");
+          error ("urlwrite: parameters (PARAM) for get and post requests must be given as a cell array of strings");
           return retval;
         }
 
-
       if (param.numel () % 2 == 1)
         {
           error ("urlwrite: number of elements in PARAM must be even");
@@ -498,17 +492,18 @@
   int nargin = args.length ();
 
   // verify arguments
-  if (nargin != 1  && nargin != 3)
+  if (nargin != 1 && nargin != 3)
     {
       print_usage ();
       return retval;
     }
 
+  // FIXME: Maybe use is_string () for better input validation.
   std::string url = args(0).string_value ();
 
   if (error_state)
     {
-      error ("urlread: URL must be a character string");
+      error ("urlread: URL must be a string");
       return retval;
     }
 
@@ -517,15 +512,10 @@
 
   if (nargin == 3)
     {
+      // FIXME: Maybe use is_string () for better input validation.
       method = args(1).string_value ();
 
-      if (error_state)
-        {
-          error ("urlread: METHOD must be \"get\" or \"post\"");
-          return retval;
-        }
-
-      if (method != "get" && method != "post")
+      if (error_state || (method != "get" && method != "post"))
         {
           error ("urlread: METHOD must be \"get\" or \"post\"");
           return retval;
@@ -535,7 +525,7 @@
 
       if (error_state)
         {
-          error ("urlread: parameters (PARAM) for get and post requests must be given as a cell array of character strings");
+          error ("urlread: parameters (PARAM) for get and post requests must be given as a cell array of strings");
           return retval;
         }
 
--- a/libinterp/corefcn/utils.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/utils.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -392,10 +392,10 @@
 
   if (nargin == 2 || nargin == 3)
     {
-      std::string path = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string path = args(0).string_value ();
 
-      if (! error_state)
-        {
           string_vector names = args(1).all_strings ();
 
           if (! error_state && names.length () > 0)
@@ -1038,7 +1038,7 @@
           if (! error_state)
             retval = octave_errno::lookup (nm);
           else
-            error ("errno: expecting character string argument");
+            error ("errno: expecting string argument");
         }
       else
         {
--- a/libinterp/corefcn/variables.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/corefcn/variables.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -150,6 +150,8 @@
 
   if (! retval)
     {
+      // FIXME: Should is_string () be used instead which will warn more
+      //        broadly about incorrect input?
       std::string s = arg.string_value ();
 
       std::string cmd = header;
@@ -341,14 +343,14 @@
       return retval;
     }
 
-  std::string name = args(0).string_value ();
-
-  if (error_state)
+  if (! args(0).is_string ())
     {
       error ("isglobal: NAME must be a string");
       return retval;
     }
 
+  std::string name = args(0).string_value ();
+
   return symbol_table::is_global (name);
 }
 
@@ -946,7 +948,7 @@
             error ("%s: value must not be empty", nm);
         }
       else
-        error ("%s: expecting arg to be a character string", nm);
+        error ("%s: expecting arg to be a string", nm);
     }
   else if (nargin > 1)
     print_usage ();
@@ -994,7 +996,7 @@
             error ("%s: value not allowed (\"%s\")", nm, sval.c_str ());
         }
       else
-        error ("%s: expecting arg to be a character string", nm);
+        error ("%s: expecting arg to be a string", nm);
     }
   else if (nargin > 1)
     print_usage ();
@@ -2076,10 +2078,11 @@
 
   if (args.length () == 1)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
-        munlock (name);
+      if (args(0).is_string ())
+        {
+          std::string name = args(0).string_value ();
+          munlock (name);
+        }
       else
         error ("munlock: FCN must be a string");
     }
@@ -2112,10 +2115,11 @@
 
   if (args.length () == 1)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
-        retval = mislocked (name);
+      if (args(0).is_string ())
+        {
+          std::string name = args(0).string_value ();
+          retval = mislocked (name);
+        }
       else
         error ("mislocked: FCN must be a string");
     }
--- a/libinterp/octave-value/ov-base.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/octave-value/ov-base.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -1597,13 +1597,13 @@
                       subs_field(i) = val;
                     else
                       {
-                        error ("expecting character string argument for '.' index");
+                        error ("string argument required for '.' index");
                         return retval;
                       }
                   }
                 else
                   {
-                    error ("expecting single argument for '.' index");
+                    error ("only single argument permitted for '.' index");
                     return retval;
                   }
               }
--- a/libinterp/octave-value/ov-class.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/octave-value/ov-class.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -1063,7 +1063,7 @@
           if (tmp(0).is_string ())
             retval = tmp(0).all_strings (pad);
           else
-            error ("cname/char method did not return a character string");
+            error ("cname/char method did not return a string");
         }
     }
   else
@@ -1923,7 +1923,7 @@
             error ("class: invalid call from outside class constructor or method");
         }
       else
-        error ("class: ID (class name) must be a character string");
+        error ("class: ID (class name) must be a string");
     }
 
   return retval;
--- a/libinterp/octave-value/ov-fcn-handle.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/octave-value/ov-fcn-handle.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -1850,10 +1850,11 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      std::string nm = args(0).string_value ();
-
-      if (! error_state)
-        retval = make_fcn_handle (nm, nargin != 2);
+      if (args(0).is_string ())
+        {
+          std::string nm = args(0).string_value ();
+          retval = make_fcn_handle (nm, nargin != 2);
+        }
       else
         error ("str2func: FCN_NAME must be a string");
     }
--- a/libinterp/octave-value/ov-java.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/octave-value/ov-java.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -2050,9 +2050,10 @@
 
       if (args.length () > 0)
         {
-          std::string classname = args(0).string_value ();
-          if (! error_state)
+          if (args(0).is_string ())
             {
+              std::string classname = args(0).string_value ();
+
               octave_value_list tmp;
               for (int i=1; i<args.length (); i++)
                 tmp(i-1) = args(i);
@@ -2114,9 +2115,10 @@
 
       if (args.length () > 1)
         {
-          std::string methodname = args(0).string_value ();
-          if (! error_state)
+          if (args(0).is_string ())
             {
+              std::string methodname = args(0).string_value ();
+
               octave_value_list tmp;
               for (int i=2; i<args.length (); i++)
                 tmp(i-2) = args(i);
@@ -2187,9 +2189,10 @@
 
       if (args.length () == 2)
         {
-          std::string name = args(1).string_value ();
-          if (! error_state)
+          if (args(1).is_string ())
             {
+              std::string name = args(1).string_value ();
+
               if (args(0).is_java ())
                 {
                   octave_java *jobj = TO_JAVA (args(0));
@@ -2249,9 +2252,10 @@
 
       if (args.length () == 3)
         {
-          std::string name = args(1).string_value ();
-          if (! error_state)
+          if (args(1).is_string ())
             {
+              std::string name = args(1).string_value ();
+
               if (args(0).is_java ())
                 {
                   octave_java *jobj = TO_JAVA (args(0));
--- a/libinterp/octave-value/ov.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/octave-value/ov.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -2874,10 +2874,9 @@
 
       for (int k = 0; k < nel; k++)
         {
-          std::string item = type(k).string_value ();
-
-          if (! error_state)
+          if (type(k).is_string ())
             {
+              std::string item = type(k).string_value ();
               if (item == "{}")
                 type_string[k] = '{';
               else if (item == "()")
@@ -2892,8 +2891,7 @@
             }
           else
             {
-              error ("%s: expecting type(%d) to be a character string",
-                     name, k+1);
+              error ("%s: type(%d) must be a string", name, k+1);
               return;
             }
 
@@ -2916,8 +2914,7 @@
             }
           else
             {
-              error ("%s: expecting subs(%d) to be a character string or cell array",
-                     name, k+1);
+              error ("%s: subs(%d) must be a string or cell array", name, k+1);
               return;
             }
 
--- a/libinterp/parse-tree/pt-idx.cc	Mon Dec 15 22:16:25 2014 -0800
+++ b/libinterp/parse-tree/pt-idx.cc	Tue Dec 16 09:21:29 2014 -0800
@@ -220,7 +220,7 @@
               if (t.is_string () && t.rows () == 1)
                 fn = t.string_value ();
               else
-                error ("dynamic structure field names must be character strings");
+                error ("dynamic structure field names must be strings");
             }
         }
       else
--- a/test/io.tst	Mon Dec 15 22:16:25 2014 -0800
+++ b/test/io.tst	Tue Dec 16 09:21:29 2014 -0800
@@ -399,8 +399,8 @@
 
 %!assert (ischar (tempname ()))
 
-%!warning tempname (1);
-%!warning tempname ("foo", 1);
+%!error <DIR must be a string> tempname (1);
+%!error <PREFIX must be a string> tempname ("foo", 1);
 
 %!error <Invalid call to tempname> tempname (1, 2, 3)
 
--- a/test/system.tst	Mon Dec 15 22:16:25 2014 -0800
+++ b/test/system.tst	Tue Dec 16 09:21:29 2014 -0800
@@ -286,11 +286,7 @@
 %!error <Invalid call to setenv> setenv ()
 %!error <Invalid call to setenv> setenv ("foo", "bar", 1)
 
-%!test
-%! wns = warning ("query", "Octave:num-to-str");
-%! warning ("on", "Octave:num-to-str");
-%! fail ("setenv (1, 2)","warning");
-%! warning (wns.state, "Octave:num-to-str");
+%!error <VAR must be a string> setenv (1, 2)
 
 %!test
 %! xdir = pwd ();