[prev in list] [next in list] [prev in thread] [next in thread] 

List:       nsis-commits
Subject:    [NSIS-commits] SF.net SVN: nsis:[6455] NSIS/trunk/Source
From:       anders_k () users ! sourceforge ! net
Date:       2014-03-30 3:25:54
Message-ID: E1WU6Ni-0001HQ-C6 () sfs-ml-1 ! v29 ! ch3 ! sourceforge ! com
[Download RAW message or body]

Revision: 6455
          http://sourceforge.net/p/nsis/code/6455
Author:   anders_k
Date:     2014-03-30 03:25:52 +0000 (Sun, 30 Mar 2014)
Log Message:
-----------
Adding the same file twice can push cur_datablock over the 2GB limit because \
datablock_optimize() happens too late. Try to find a dupe early.

Modified Paths:
--------------
    NSIS/trunk/Source/build.cpp
    NSIS/trunk/Source/build.h

Modified: NSIS/trunk/Source/build.cpp
===================================================================
--- NSIS/trunk/Source/build.cpp	2014-03-28 17:10:02 UTC (rev 6454)
+++ NSIS/trunk/Source/build.cpp	2014-03-30 03:25:52 UTC (rev 6455)
@@ -779,10 +779,7 @@
         db->release(oldstuff, l);
         db->release();
 
-        if (res)
-        {
-          break;
-        }
+        if (res) break;
 
         left -= l;
       }
@@ -799,10 +796,39 @@
   }
 
   db->setro(FALSE);
-
   return start_offset;
 }
 
+bool CEXEBuild::datablock_finddata(IMMap&mmap, int mmstart, int size, int*ofs)
+{
+  const int first_int = size;
+  size &= ~ 0x80000000;
+  MMapBuf *db = (MMapBuf *) cur_datablock;
+  cached_db_size *db_sizes = (cached_db_size *) this->cur_datablock_cache->get();
+  int db_sizes_num = this->cur_datablock_cache->getlen() / sizeof(cached_db_size);
+  for (int i = 0; i < db_sizes_num; i++)
+  {
+    if (db_sizes[i].first_int != first_int) continue;
+    int left = size, oldpos = db_sizes[i].start_offset;
+    while (left > 0)
+    {
+      int cbCmp = min(left, build_filebuflen);
+      void *newstuff = mmap.get(mmstart + size - left, cbCmp);
+      void *oldstuff = db->get(sizeof(int) + oldpos + size - left, cbCmp);
+      int res = memcmp(newstuff, oldstuff, cbCmp);
+      mmap.release(), db->release();
+      if (res) break;
+      left -= cbCmp;
+    }
+    if (!left)
+    {
+      if (ofs) *ofs = oldpos;
+      return true;
+    }
+  }
+  return false;
+}
+
 int CEXEBuild::add_db_data(IMMap *mmap) // returns offset
 {
   build_compressor_set = true;
@@ -924,7 +950,15 @@
 
   if (!done)
   {
-    db->resize(st + length + sizeof(int));
+    // Adding the same file twice can push cur_datablock over the limit
+    // because datablock_optimize() happens too late. Let's try to find a dupe \
early. +    if (this->build_optimize_datablock && st + sizeof(int) + length < 0)
+    {
+      int oldst;
+      if (datablock_finddata(*mmap, 0, length, &oldst)) return oldst;
+    }
+
+    db->resize(st + sizeof(int) + length);
     int *plen = (int *) db->get(st, sizeof(int));
     *plen = FIX_ENDIAN_INT32(length);
     db->release();
@@ -945,7 +979,6 @@
   }
 
   db_full_size += length + sizeof(int);
-
   return st;
 }
 

Modified: NSIS/trunk/Source/build.h
===================================================================
--- NSIS/trunk/Source/build.h	2014-03-28 17:10:02 UTC (rev 6454)
+++ NSIS/trunk/Source/build.h	2014-03-30 03:25:52 UTC (rev 6455)
@@ -278,6 +278,7 @@
 
     // build.cpp functions used mostly within build.cpp
     int datablock_optimize(int start_offset, int first_int);
+    bool datablock_finddata(IMMap&mmap, int mmstart, int size, int*ofs);
     void printline(int l);
     int process_jump(LineParser &line, int wt, int *offs);
 

This was sent by the SourceForge.net collaborative development platform, the world's \
largest Open Source development site.


------------------------------------------------------------------------------
_______________________________________________
NSIS-commits mailing list
NSIS-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nsis-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic