Blame SOURCES/djvulibre-3.5.27-stack-overflow.patch

a9380a
From e15d51510048927f172f1bf1f27ede65907d940d Mon Sep 17 00:00:00 2001
a9380a
From: Leon Bottou <leon@bottou.org>
a9380a
Date: Mon, 8 Apr 2019 22:25:55 -0400
a9380a
Subject: bug 299 fixed
a9380a
a9380a
a9380a
diff --git a/libdjvu/GContainer.h b/libdjvu/GContainer.h
a9380a
index 96b067c..0140211 100644
a9380a
--- a/libdjvu/GContainer.h
a9380a
+++ b/libdjvu/GContainer.h
a9380a
@@ -550,52 +550,61 @@ public:
a9380a
 template <class TYPE> void
a9380a
 GArrayTemplate<TYPE>::sort(int lo, int hi)
a9380a
 {
a9380a
-  if (hi <= lo)
a9380a
-    return;
a9380a
-  if (hi > hibound || lo
a9380a
-    G_THROW( ERR_MSG("GContainer.illegal_subscript") );
a9380a
   TYPE *data = (TYPE*)(*this);
a9380a
-  // Test for insertion sort
a9380a
-  if (hi <= lo + 50)
a9380a
+  while(true)
a9380a
     {
a9380a
-      for (int i=lo+1; i<=hi; i++)
a9380a
+      if (hi <= lo)
a9380a
+        return;
a9380a
+      if (hi > hibound || lo
a9380a
+        G_THROW( ERR_MSG("GContainer.illegal_subscript") );
a9380a
+      // Test for insertion sort
a9380a
+      if (hi <= lo + 50)
a9380a
         {
a9380a
-          int j = i;
a9380a
-          TYPE tmp = data[i];
a9380a
-          while ((--j>=lo) && !(data[j]<=tmp))
a9380a
-            data[j+1] = data[j];
a9380a
-          data[j+1] = tmp;
a9380a
+          for (int i=lo+1; i<=hi; i++)
a9380a
+            {
a9380a
+              int j = i;
a9380a
+              TYPE tmp = data[i];
a9380a
+              while ((--j>=lo) && !(data[j]<=tmp))
a9380a
+                data[j+1] = data[j];
a9380a
+              data[j+1] = tmp;
a9380a
+            }
a9380a
+          return;
a9380a
         }
a9380a
-      return;
a9380a
-    }
a9380a
-  // -- determine suitable quick-sort pivot
a9380a
-  TYPE tmp = data[lo];
a9380a
-  TYPE pivot = data[(lo+hi)/2];
a9380a
-  if (pivot <= tmp)
a9380a
-    { tmp = pivot; pivot=data[lo]; }
a9380a
-  if (data[hi] <= tmp)
a9380a
-    { pivot = tmp; }
a9380a
-  else if (data[hi] <= pivot)
a9380a
-    { pivot = data[hi]; }
a9380a
-  // -- partition set
a9380a
-  int h = hi;
a9380a
-  int l = lo;
a9380a
-  while (l < h)
a9380a
-    {
a9380a
-      while (! (pivot <= data[l])) l++;
a9380a
-      while (! (data[h] <= pivot)) h--;
a9380a
-      if (l < h)
a9380a
+      // -- determine median-of-three pivot
a9380a
+      TYPE tmp = data[lo];
a9380a
+      TYPE pivot = data[(lo+hi)/2];
a9380a
+      if (pivot <= tmp)
a9380a
+        { tmp = pivot; pivot=data[lo]; }
a9380a
+      if (data[hi] <= tmp)
a9380a
+        { pivot = tmp; }
a9380a
+      else if (data[hi] <= pivot)
a9380a
+        { pivot = data[hi]; }
a9380a
+      // -- partition set
a9380a
+      int h = hi;
a9380a
+      int l = lo;
a9380a
+      while (l < h)
a9380a
         {
a9380a
-          tmp = data[l];
a9380a
-          data[l] = data[h];
a9380a
-          data[h] = tmp;
a9380a
-          l = l+1;
a9380a
-          h = h-1;
a9380a
+          while (! (pivot <= data[l])) l++;
a9380a
+          while (! (data[h] <= pivot)) h--;
a9380a
+          if (l < h)
a9380a
+            {
a9380a
+              tmp = data[l];
a9380a
+              data[l] = data[h];
a9380a
+              data[h] = tmp;
a9380a
+              l = l+1;
a9380a
+              h = h-1;
a9380a
+            }
a9380a
+        }
a9380a
+      // -- recurse, small partition first
a9380a
+      //    tail-recursion elimination
a9380a
+      if (h - lo <= hi - l) {
a9380a
+        sort(lo,h);
a9380a
+        lo = l; // sort(l,hi)
a9380a
+      } else {
a9380a
+        sort(l,hi);
a9380a
+        hi = h; // sort(lo,h)
a9380a
       }
a9380a
     }
a9380a
-  // -- recursively restart
a9380a
-  sort(lo, h);
a9380a
-  sort(l, hi);
a9380a
 }
a9380a
 
a9380a
 template<class TYPE> inline TYPE&