List:Commits« Previous MessageNext Message »
From:knielsen Date:March 9 2007 11:37pm
Subject:bk commit into 5.0 tree (knielsen:1.2447) BUG#27018
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of knielsen. When knielsen does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-03-09 23:37:33+01:00, knielsen@ymer.(none) +2 -0
  BUG#27018: Partial blob write inside blob clobbers data after the write.
  
  When doing partial blob update with NdbBlob::writeData(), zero-padding
  after the write was wrongly done, causing part of the old blob value
  to be overwritten with zeros (or spaces for text field).
  
  Fixed by only padding when needed (when writing at end of the blob).

  ndb/src/ndbapi/NdbBlob.cpp@stripped, 2007-03-09 23:37:29+01:00, knielsen@ymer.(none) +3 -1
    Do not pad rest of blob part after the write, unless it is a write at the
    end of the blob.

  ndb/test/ndbapi/testBlobs.cpp@stripped, 2007-03-09 23:37:29+01:00, knielsen@ymer.(none) +53
-1
    Add test case.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	knielsen
# Host:	ymer.(none)
# Root:	/usr/local/mysql/mysql-5.0-ndb

--- 1.31/ndb/test/ndbapi/testBlobs.cpp	2007-03-09 23:37:38 +01:00
+++ 1.32/ndb/test/ndbapi/testBlobs.cpp	2007-03-09 23:37:38 +01:00
@@ -138,6 +138,7 @@ printusage()
     << "  2           readData / writeData" << endl
     << "bug tests (no blob test)" << endl
     << "  -bug 4088   ndb api hang with mixed ops on index table" << endl
+    << "  -bug 27018  middle partial part write clobbers rest of part" <<
endl
     << "  -bug nnnn   delete + write gives 626" << endl
     << "  -bug nnnn   acc crash on delete and long key" << endl
     ;
@@ -1807,6 +1808,56 @@ bugtest_4088()
 }
 
 static int
+bugtest_27018()
+{
+  DBG("bug test 27018 - middle partial part write clobbers rest of part");
+
+  // insert rows
+  calcTups(false);
+  CHK(insertPk(false) == 0);
+  // new trans
+  for (unsigned k= 0; k < g_opt.m_rows; k++)
+  {
+    Tup& tup= g_tups[k];
+
+    CHK((g_con= g_ndb->startTransaction()) != 0);
+    CHK((g_opr= g_con->getNdbOperation(g_opt.m_tname)) != 0);
+    CHK(g_opr->updateTuple() == 0);
+    CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
+    if (g_opt.m_pk2len != 0)
+      CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+    CHK(getBlobHandles(g_opr) == 0);
+    CHK(g_con->execute(NoCommit) == 0);
+
+    /* Update one byte in random position. */
+    Uint32 offset= urandom(tup.m_blob1.m_len);
+    tup.m_blob1.m_buf[0]= 0xff ^ tup.m_blob1.m_val[offset];
+    CHK(g_bh1->setPos(offset) == 0);
+    CHK(g_bh1->writeData(&(tup.m_blob1.m_buf[0]), 1) == 0);
+    CHK(g_con->execute(Commit) == 0);
+    g_ndb->closeTransaction(g_con);
+
+    CHK((g_con= g_ndb->startTransaction()) != 0);
+    CHK((g_opr= g_con->getNdbOperation(g_opt.m_tname)) != 0);
+    CHK(g_opr->readTuple() == 0);
+    CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
+    if (g_opt.m_pk2len != 0)
+      CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+    CHK(getBlobHandles(g_opr) == 0);
+
+    CHK(g_bh1->getValue(tup.m_blob1.m_buf, tup.m_blob1.m_len) == 0);
+    CHK(g_con->execute(Commit) == 0);
+    Uint64 len= ~0;
+    CHK(g_bh1->getLength(len) == 0 && len == tup.m_blob1.m_len);
+    tup.m_blob1.m_buf[offset]^= 0xff;
+    CHK(memcmp(tup.m_blob1.m_buf, tup.m_blob1.m_val, tup.m_blob1.m_len) == 0);
+    g_ndb->closeTransaction(g_con);
+  }
+
+  return 0;
+}
+
+static int
 bugtest_2222()
 {
   return 0;
@@ -1822,7 +1873,8 @@ static struct {
   int m_bug;
   int (*m_test)();
 } g_bugtest[] = {
-  { 4088, bugtest_4088 }
+  { 4088, bugtest_4088 },
+  { 27018, bugtest_27018 }
 };
 
 NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535)

--- 1.32/ndb/src/ndbapi/NdbBlob.cpp	2007-03-09 23:37:38 +01:00
+++ 1.33/ndb/src/ndbapi/NdbBlob.cpp	2007-03-09 23:37:38 +01:00
@@ -800,7 +800,9 @@ NdbBlob::writeDataPrivate(const char* bu
         DBUG_RETURN(-1);
       Uint32 n = thePartSize - off;
       if (n > len) {
-        memset(thePartBuf.data + off + len, theFillChar, n - len);
+        /* If we are adding data at the end, fill rest of part. */
+        if (pos + len >= theLength)
+          memset(thePartBuf.data + off + len, theFillChar, n - len);
         n = len;
       }
       memcpy(thePartBuf.data + off, buf, n);
Thread
bk commit into 5.0 tree (knielsen:1.2447) BUG#27018knielsen9 Mar