public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Ian Lance Taylor <iant@google.com>
To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com
Subject: [gccgo] Check for overflow when converting from string to int
Date: Wed, 17 Nov 2010 22:43:00 -0000	[thread overview]
Message-ID: <mcrr5ejy5qm.fsf@google.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 497 bytes --]

Joseph Myers pointed out that the Go frontend calls atoi in a few
places, and has a case where it calls strtol without checking for
overflow.  None of these are critical cases.  The calls to atoi are all
when parsing import data which is generated by the compiler.  The strtol
is when parsing a //line comment which sets the line number for debug
info like #line in C.  However, testing for overflow is the right thing
to do anyhow, and this patch implements it.  Committed to gccgo branch.

Ian


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: overflow --]
[-- Type: text/x-diff, Size: 2613 bytes --]

diff -r bd850168de12 go/import.cc
--- a/go/import.cc	Wed Nov 17 11:34:11 2010 -0800
+++ b/go/import.cc	Wed Nov 17 13:52:23 2010 -0800
@@ -311,7 +311,10 @@
 
       this->require_c_string("priority ");
       std::string priority_string = this->read_identifier();
-      this->package_->set_priority(atoi(priority_string.c_str()));
+      int prio;
+      if (!this->string_to_int(priority_string, false, &prio))
+	return NULL;
+      this->package_->set_priority(prio);
       this->require_c_string(";\n");
 
       if (stream->match_c_string("import "))
@@ -368,7 +371,9 @@
       std::string init_name = this->read_identifier();
       this->require_c_string(" ");
       std::string prio_string = this->read_identifier();
-      int prio = atoi(prio_string.c_str());
+      int prio;
+      if (!this->string_to_int(prio_string, false, &prio))
+	return;
       gogo->add_import_init_fn(package_name, init_name, prio);
     }
   this->require_c_string(";\n");
@@ -480,7 +485,10 @@
 	break;
       number += c;
     }
-  int index = atoi(number.c_str());
+
+  int index;
+  if (!this->string_to_int(number, true, &index))
+    return Type::make_error_type();
 
   if (c == '>')
     {
@@ -732,6 +740,24 @@
   return ret;
 }
 
+// Turn a string into a integer with appropriate error handling.
+
+bool
+Import::string_to_int(const std::string &s, bool is_neg_ok, int* ret)
+{
+  char* end;
+  long prio = strtol(s.c_str(), &end, 10);
+  if (*end != '\0' || prio > 0x7fffffff || (prio < 0 && !is_neg_ok))
+    {
+      error_at(this->location_, "invalid integer in import data at %d",
+	       this->stream_->pos());
+      this->stream_->set_saw_error();
+      return false;
+    }
+  *ret = prio;
+  return true;
+}
+
 // Class Import::Stream.
 
 Import::Stream::Stream()
diff -r bd850168de12 go/import.h
--- a/go/import.h	Wed Nov 17 11:34:11 2010 -0800
+++ b/go/import.h	Wed Nov 17 13:52:23 2010 -0800
@@ -237,6 +237,10 @@
   void
   register_builtin_type(Gogo*, const char* name, Builtin_code);
 
+  // Get an integer from a string.
+  bool
+  string_to_int(const std::string&, bool is_neg_ok, int* ret);
+
   // The general IR.
   Gogo* gogo_;
   // The stream from which to read import data.
diff -r bd850168de12 go/lex.cc
--- a/go/lex.cc	Wed Nov 17 11:34:11 2010 -0800
+++ b/go/lex.cc	Wed Nov 17 13:52:23 2010 -0800
@@ -1599,7 +1599,9 @@
 	  if (plend > pcolon + 1
 	      && (plend == pend
 		  || *plend < '0'
-		  || *plend > '9'))
+		  || *plend > '9')
+	      && lineno > 0
+	      && lineno < 0x7fffffff)
 	    {
 	      unsigned int filelen = pcolon - p;
 	      char* file = new char[filelen + 1];

                 reply	other threads:[~2010-11-17 21:56 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=mcrr5ejy5qm.fsf@google.com \
    --to=iant@google.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gofrontend-dev@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).