2007-10-27 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / class / corlib / System / Array.cs
index 0635c314001504a98a166f2e52ff031acf116b57..b0653b0169a5da70c7b59b05bbeca7238b9ac337 100644 (file)
@@ -116,7 +116,9 @@ namespace System
                        if (this.Rank > 1)
                                throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
                        if (index + this.GetLength (0) > array.GetLowerBound (0) + array.GetLength (0))
-                               throw new ArgumentException ();
+                               throw new ArgumentException ("Destination array was not long " +
+                                       "enough. Check destIndex and length, and the array's " +
+                                       "lower bounds.");
                        if (array.Rank > 1)
                                throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
                        if (index < 0)
@@ -838,7 +840,9 @@ namespace System
                        int iCmp = 0;
                        try {
                                while (iMin <= iMax) {
-                                       int iMid = (iMin + iMax) / 2;
+                                       // Be careful with overflow
+                                       // http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html
+                                       int iMid = iMin + ((iMax - iMin) / 2);
                                        object elt = array.GetValueImpl (iMid);
 
                                        iCmp = comparer.Compare (elt, value);
@@ -937,9 +941,19 @@ namespace System
                        int dest_pos = destinationIndex - destinationArray.GetLowerBound (0);
 
                        // re-ordered to avoid possible integer overflow
-                       if (source_pos > sourceArray.Length - length || dest_pos > destinationArray.Length - length)
+                       if (source_pos > sourceArray.Length - length)
                                throw new ArgumentException ("length");
 
+                       if (dest_pos > destinationArray.Length - length) {
+                               string msg = "Destination array was not long enough. Check " +
+                                       "destIndex and length, and the array's lower bounds";
+#if NET_2_0
+                               throw new ArgumentException (msg, string.Empty);
+#else
+                               throw new ArgumentException (msg);
+#endif
+                       }
+
                        if (sourceArray.Rank != destinationArray.Rank)
                                throw new RankException (Locale.GetText ("Arrays must be of same size."));
 
@@ -1474,7 +1488,9 @@ namespace System
                        int low = low0;
                        int high = high0;
 
-                       object objPivot = keys.GetValueImpl ((low + high) / 2);
+                       // Be careful with overflows
+                       int mid = low + ((high - low) / 2);
+                       object objPivot = keys.GetValueImpl (mid);
 
                        while (low <= high) {
                                // Move the walls in
@@ -1672,7 +1688,9 @@ namespace System
                        int low = low0;
                        int high = high0;
 
-                       K keyPivot = keys [(low + high) / 2];
+                       // Be careful with overflows
+                       int mid = low + ((high - low) / 2);
+                       K keyPivot = keys [mid];
 
                        while (low <= high) {
                                // Move the walls in
@@ -1721,7 +1739,9 @@ namespace System
                        int low = low0;
                        int high = high0;
 
-                       T keyPivot = array [(low + high) / 2];
+                       // Be careful with overflows
+                       int mid = low + ((high - low) / 2);
+                       T keyPivot = array [mid];
 
                        while (low <= high) {
                                // Move the walls in
@@ -1781,7 +1801,9 @@ namespace System
                        if (this.Rank > 1)
                                throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
                        if (index + this.GetLength (0) > array.GetLowerBound (0) + array.GetLength (0))
-                               throw new ArgumentException ();
+                               throw new ArgumentException ("Destination array was not long " +
+                                       "enough. Check destIndex and length, and the array's " +
+                                       "lower bounds.");
                        if (array.Rank > 1)
                                throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
                        if (index < 0)
@@ -2036,7 +2058,8 @@ namespace System
                        int iCmp = 0;
                        try {
                                while (iMin <= iMax) {
-                                       int iMid = (iMin + iMax) / 2;
+                                       // Be careful with overflows
+                                       int iMid = iMin + ((iMax - iMin) / 2);
                                        iCmp = comparer.Compare (value, array [iMid]);
 
                                        if (iCmp == 0)