The branch, master has been updated
       via  dfedbae testtools: Import newer upstream revision.
       via  1fc1be4 Fix regf.idl, subkey and rootkey types were switched.
       via  7efcb3c Fix file corruption (non-updated header) on new allocation.
       via  d0cef92 Fix crash when no subkeys exist. Fix writing outside of 
buffer error by regf backend.
       via  2c3f560 Add python bindings for open_hive function to be able to 
load REGF files.
      from  5d80710 s4/fsmo: Naming master support added

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit dfedbaeb055acb0d7abf74b9534308149a018ee4
Author: Jelmer Vernooij <jel...@samba.org>
Date:   Sun Sep 19 12:29:42 2010 -0700

    testtools: Import newer upstream revision.
    
    This fixes (among other things) a warning during 'make test' on systems 
with Python 2.6.

commit 1fc1be4685667f95e855fd2f781651c341e06fbd
Author: wi...@baanhofman.nl <wi...@baanhofman.nl>
Date:   Mon Aug 30 12:17:41 2010 +0200

    Fix regf.idl, subkey and rootkey types were switched.
    
    Signed-off-by: Jelmer Vernooij <jel...@samba.org>

commit 7efcb3ca66b12972de3707164c7bd415619a4bb8
Author: wi...@baanhofman.nl <wi...@baanhofman.nl>
Date:   Mon Jul 26 23:00:43 2010 +0200

    Fix file corruption (non-updated header) on new allocation.
    
    Also fixes debug messages to use hex offsets.
    
    Signed-off-by: Jelmer Vernooij <jel...@samba.org>

commit d0cef92532f7c943e1c70d49ed96f090235b928e
Author: wi...@baanhofman.nl <wi...@baanhofman.nl>
Date:   Mon Jul 26 20:13:22 2010 +0200

    Fix crash when no subkeys exist. Fix writing outside of buffer error by 
regf backend.
    
    Signed-off-by: Jelmer Vernooij <jel...@samba.org>

commit 2c3f56098b0322db2e74e860a0f236fde9f74bbc
Author: wi...@baanhofman.nl <wi...@baanhofman.nl>
Date:   Mon Jul 26 12:32:32 2010 +0200

    Add python bindings for open_hive function to be able to load REGF files.
    
    Signed-off-by: Jelmer Vernooij <jel...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/testtools/NEWS                              |   45 +++++++++++++---------
 lib/testtools/testtools/matchers.py             |    9 ++++
 lib/testtools/testtools/testcase.py             |   29 +++++++-------
 lib/testtools/testtools/tests/test_testtools.py |   32 +++++++++++++--
 source4/lib/registry/pyregistry.c               |   47 +++++++++++++++++++++--
 source4/lib/registry/regf.c                     |   40 ++++++++++++++-----
 source4/lib/registry/regf.idl                   |    4 +-
 7 files changed, 153 insertions(+), 53 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/testtools/NEWS b/lib/testtools/NEWS
index dc5e6df..596df0d 100644
--- a/lib/testtools/NEWS
+++ b/lib/testtools/NEWS
@@ -4,6 +4,15 @@ testtools NEWS
 NEXT
 ~~~~
 
+Improvements
+------------
+
+* Code duplication between assertEqual and the matcher Equals has been removed.
+
+* In normal circumstances, a TestCase will no longer share details with clones
+  of itself. (Andrew Bennetts, bug #637725)
+
+
 0.9.6
 ~~~~~
 
@@ -17,32 +26,32 @@ patches and TestCase.assertEqual gives slightly nicer 
errors.
 Improvements
 ------------
 
- * 'TestCase.assertEqual' now formats errors a little more nicely, in the
-   style of bzrlib.
+* 'TestCase.assertEqual' now formats errors a little more nicely, in the
+  style of bzrlib.
 
- * Added `PlaceHolder` and `ErrorHolder`, TestCase-like objects that can be
-   used to add results to a `TestResult`.
+* Added `PlaceHolder` and `ErrorHolder`, TestCase-like objects that can be
+  used to add results to a `TestResult`.
 
- * 'Mismatch' now takes optional description and details parameters, so
-   custom Matchers aren't compelled to make their own subclass.
+* 'Mismatch' now takes optional description and details parameters, so
+  custom Matchers aren't compelled to make their own subclass.
 
- * jml added a built-in UTF8_TEXT ContentType to make it slightly easier to
-   add details to test results. See bug #520044.
+* jml added a built-in UTF8_TEXT ContentType to make it slightly easier to
+  add details to test results. See bug #520044.
 
- * Fix a bug in our built-in matchers where assertThat would blow up if any
-   of them failed. All built-in mismatch objects now provide get_details().
+* Fix a bug in our built-in matchers where assertThat would blow up if any
+  of them failed. All built-in mismatch objects now provide get_details().
 
- * New 'Is' matcher, which lets you assert that a thing is identical to
-   another thing.
+* New 'Is' matcher, which lets you assert that a thing is identical to
+  another thing.
 
- * New 'LessThan' matcher which lets you assert that a thing is less than
-   another thing.
+* New 'LessThan' matcher which lets you assert that a thing is less than
+  another thing.
 
- * TestCase now has a 'patch()' method to make it easier to monkey-patching
-   objects in tests. See the manual for more information. Fixes bug #310770.
+* TestCase now has a 'patch()' method to make it easier to monkey-patching
+  objects in tests. See the manual for more information. Fixes bug #310770.
 
- * MultiTestResult methods now pass back return values from the results it
-   forwards to.
+* MultiTestResult methods now pass back return values from the results it
+  forwards to.
 
 0.9.5
 ~~~~~
diff --git a/lib/testtools/testtools/matchers.py 
b/lib/testtools/testtools/matchers.py
index 6a4c82a..61b5bd7 100644
--- a/lib/testtools/testtools/matchers.py
+++ b/lib/testtools/testtools/matchers.py
@@ -25,6 +25,7 @@ __all__ = [
 
 import doctest
 import operator
+from pprint import pformat
 
 
 class Matcher(object):
@@ -178,6 +179,14 @@ class _BinaryMismatch(Mismatch):
         self.other = other
 
     def describe(self):
+        left = repr(self.expected)
+        right = repr(self.other)
+        if len(left) + len(right) > 70:
+            return "%s:\nreference = %s\nactual = %s\n" % (
+                self._mismatch_string, pformat(self.expected),
+                pformat(self.other))
+        else:
+            return "%s %s %s" % (left, self._mismatch_string,right)
         return "%r %s %r" % (self.expected, self._mismatch_string, self.other)
 
 
diff --git a/lib/testtools/testtools/testcase.py 
b/lib/testtools/testtools/testcase.py
index 48eec71..959c129 100644
--- a/lib/testtools/testtools/testcase.py
+++ b/lib/testtools/testtools/testcase.py
@@ -17,13 +17,16 @@ try:
 except ImportError:
     wraps = None
 import itertools
-from pprint import pformat
 import sys
 import types
 import unittest
 
 from testtools import content
 from testtools.compat import advance_iterator
+from testtools.matchers import (
+    Annotate,
+    Equals,
+    )
 from testtools.monkey import patch
 from testtools.runtest import RunTest
 from testtools.testresult import TestResult
@@ -81,7 +84,9 @@ class TestCase(unittest.TestCase):
         self._traceback_id_gen = itertools.count(0)
         self.__setup_called = False
         self.__teardown_called = False
-        self.__details = {}
+        # __details is lazy-initialized so that a constructed-but-not-run
+        # TestCase is safe to use with clone_test_with_new_id.
+        self.__details = None
         self.__RunTest = kwargs.get('runTest', RunTest)
         self.__exception_handlers = []
         self.exception_handlers = [
@@ -114,6 +119,8 @@ class TestCase(unittest.TestCase):
         :param content_object: The content object for this detail. See
             testtools.content for more detail.
         """
+        if self.__details is None:
+            self.__details = {}
         self.__details[name] = content_object
 
     def getDetails(self):
@@ -121,6 +128,8 @@ class TestCase(unittest.TestCase):
 
         For more details see pydoc testtools.TestResult.
         """
+        if self.__details is None:
+            self.__details = {}
         return self.__details
 
     def patch(self, obj, attribute, value):
@@ -230,18 +239,10 @@ class TestCase(unittest.TestCase):
         :param observed: The observed value.
         :param message: An optional message to include in the error.
         """
-        try:
-            return super(TestCase, self).assertEqual(expected, observed)
-        except self.failureException:
-            lines = []
-            if message:
-                lines.append(message)
-            lines.extend(
-                ["not equal:",
-                 "a = %s" % pformat(expected),
-                 "b = %s" % pformat(observed),
-                 ''])
-            self.fail('\n'.join(lines))
+        matcher = Equals(expected)
+        if message:
+            matcher = Annotate(message, matcher)
+        self.assertThat(observed, matcher)
 
     failUnlessEqual = assertEquals = assertEqual
 
diff --git a/lib/testtools/testtools/tests/test_testtools.py 
b/lib/testtools/testtools/tests/test_testtools.py
index 9edc5a5..5dfb355 100644
--- a/lib/testtools/testtools/tests/test_testtools.py
+++ b/lib/testtools/testtools/tests/test_testtools.py
@@ -461,6 +461,15 @@ class TestAssertions(TestCase):
              'a = %s' % pformat(a),
              'b = %s' % pformat(b),
              ''])
+        expected_error = '\n'.join([
+            'Match failed. Matchee: "%r"' % b,
+            'Matcher: Annotate(%r, Equals(%r))' % (message, a),
+            'Difference: !=:',
+            'reference = %s' % pformat(a),
+            'actual = %s' % pformat(b),
+            ': ' + message,
+            ''
+            ])
         self.assertFails(expected_error, self.assertEqual, a, b, message)
         self.assertFails(expected_error, self.assertEquals, a, b, message)
         self.assertFails(expected_error, self.failUnlessEqual, a, b, message)
@@ -468,11 +477,12 @@ class TestAssertions(TestCase):
     def test_assertEqual_formatting_no_message(self):
         a = "cat"
         b = "dog"
-        expected_error = '\n'.join(
-            ['not equal:',
-             'a = %s' % pformat(a),
-             'b = %s' % pformat(b),
-             ''])
+        expected_error = '\n'.join([
+            'Match failed. Matchee: "dog"',
+            'Matcher: Equals(\'cat\')',
+            'Difference: \'cat\' != \'dog\'',
+            ''
+            ])
         self.assertFails(expected_error, self.assertEqual, a, b)
         self.assertFails(expected_error, self.assertEquals, a, b)
         self.assertFails(expected_error, self.failUnlessEqual, a, b)
@@ -760,6 +770,18 @@ class TestCloneTestWithNewId(TestCase):
         self.assertEqual(oldName, test.id(),
             "the original test instance should be unchanged.")
 
+    def test_cloned_testcase_does_not_share_details(self):
+        """A cloned TestCase does not share the details dict."""
+        class Test(TestCase):
+            def test_foo(self):
+                self.addDetail(
+                    'foo', content.Content('text/plain', lambda: 'foo'))
+        orig_test = Test('test_foo')
+        cloned_test = clone_test_with_new_id(orig_test, self.getUniqueString())
+        orig_test.run(unittest.TestResult())
+        self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes())
+        self.assertEqual(None, cloned_test.getDetails().get('foo'))
+
 
 class TestDetailsProvided(TestWithDetails):
 
diff --git a/source4/lib/registry/pyregistry.c 
b/source4/lib/registry/pyregistry.c
index 7f4f833..1373ed8 100644
--- a/source4/lib/registry/pyregistry.c
+++ b/source4/lib/registry/pyregistry.c
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    Samba utility functions
    Copyright (C) Jelmer Vernooij <jel...@samba.org> 2008
+   Copyright (C) Wilco Baan Hofman <wi...@baanhofman.nl> 2010
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -238,16 +239,53 @@ static PyMethodDef hive_key_methods[] = {
        { NULL }
 };
 
-static PyObject *hive_open(PyTypeObject *type, PyObject *args, PyObject 
*kwargs)
-{
-       /* reg_open_hive */
+static PyObject *hive_new(PyTypeObject *type, PyObject *args, PyObject 
*kwargs) {
        Py_RETURN_NONE;
 }
 
+static PyObject *py_open_hive(PyTypeObject *type, PyObject *args, PyObject 
*kwargs)
+{
+       const char *kwnames[] = { "location", "lp_ctx", "session_info", 
"credentials", NULL };
+       WERROR result;
+       struct loadparm_context *lp_ctx;
+       PyObject *py_lp_ctx, *py_session_info, *py_credentials;
+       struct auth_session_info *session_info;
+       struct cli_credentials *credentials;
+       char *location;
+       struct hive_key *hive_key;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOO",
+                                        discard_const_p(char *, kwnames),
+                                        &location,
+                                        &py_lp_ctx, &py_session_info,
+                                        &py_credentials))
+               return NULL;
+
+       lp_ctx = lpcfg_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */
+       if (lp_ctx == NULL) {
+               PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
+               return NULL;
+       }
+
+       credentials = cli_credentials_from_py_object(py_credentials);
+       if (credentials == NULL) {
+               PyErr_SetString(PyExc_TypeError, "Expected credentials");
+               return NULL;
+       }
+       session_info = NULL;
+
+       result = reg_open_hive(NULL, location, session_info, credentials,
+                              tevent_context_init(NULL),
+                              lp_ctx, &hive_key);
+       PyErr_WERROR_IS_ERR_RAISE(result);
+
+       return py_talloc_steal(&PyHiveKey, hive_key);
+}
+
 PyTypeObject PyHiveKey = {
        .tp_name = "HiveKey",
        .tp_methods = hive_key_methods,
-       .tp_new = hive_open,
+       .tp_new = hive_new,
        .tp_basicsize = sizeof(py_talloc_Object),
        .tp_dealloc = py_talloc_dealloc,
        .tp_flags = Py_TPFLAGS_DEFAULT,
@@ -396,6 +434,7 @@ static PyMethodDef py_registry_methods[] = {
        { "open_directory", py_open_directory, METH_VARARGS, 
"open_dir(location) -> key" },
        { "create_directory", py_create_directory, METH_VARARGS, 
"create_dir(location) -> key" },
        { "open_ldb", (PyCFunction)py_open_ldb_file, 
METH_VARARGS|METH_KEYWORDS, "open_ldb(location, session_info=None, 
credentials=None, loadparm_context=None) -> key" },
+       { "open_hive", (PyCFunction)py_open_hive, METH_VARARGS|METH_KEYWORDS, 
"open_hive(location, session_info=None, credentials=None, 
loadparm_context=None) -> key" },
        { "str_regtype", py_str_regtype, METH_VARARGS, "str_regtype(int) -> 
str" },
        { "get_predef_name", py_get_predef_name, METH_VARARGS, 
"get_predef_name(hkey) -> str" },
        { NULL }
diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c
index cfbaadd..b62109e 100644
--- a/source4/lib/registry/regf.c
+++ b/source4/lib/registry/regf.c
@@ -110,7 +110,7 @@ static DATA_BLOB hbin_get(const struct regf_data *data, 
uint32_t offset)
        hbin = hbin_by_offset(data, offset, &rel_offset);
 
        if (hbin == NULL) {
-               DEBUG(1, ("Can't find HBIN containing 0x%04x\n", offset));
+               DEBUG(1, ("Can't find HBIN at 0x%04x\n", offset));
                return ret;
        }
 
@@ -216,6 +216,8 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, 
uint32_t size,
        if (data->hbins[i] == NULL) {
                DEBUG(4, ("No space available in other HBINs for block of size 
%d, allocating new HBIN\n",
                        size));
+
+               /* Add extra hbin block */
                data->hbins = talloc_realloc(data, data->hbins,
                                             struct hbin_block *, i+2);
                hbin = talloc(data->hbins, struct hbin_block);
@@ -224,17 +226,22 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, 
uint32_t size,
                data->hbins[i] = hbin;
                data->hbins[i+1] = NULL;
 
+               /* Set hbin data */
                hbin->HBIN_ID = talloc_strdup(hbin, "hbin");
                hbin->offset_from_first = (i == 
0?0:data->hbins[i-1]->offset_from_first+data->hbins[i-1]->offset_to_next);
                hbin->offset_to_next = 0x1000;
                hbin->unknown[0] = 0;
-               hbin->unknown[0] = 0;
+               hbin->unknown[1] = 0;
                unix_to_nt_time(&hbin->last_change, time(NULL));
                hbin->block_size = hbin->offset_to_next;
                hbin->data = talloc_zero_array(hbin, uint8_t, hbin->block_size 
- 0x20);
+               /* Update the regf header */
+               data->header->last_block += hbin->offset_to_next;
 
-               rel_offset = 0x0;
+               /* Set the next block to it's proper size and set the
+                * rel_offset for this block */
                SIVAL(hbin->data, size, hbin->block_size - size - 0x20);
+               rel_offset = 0x0;
        }
 
        /* Set size and mark as used */
@@ -314,7 +321,7 @@ static void hbin_free (struct regf_data *data, uint32_t 
offset)
        size = -size;
 
        /* If the next block is free, merge into big free block */
-       if (rel_offset + size < hbin->offset_to_next) {
+       if (rel_offset + size < hbin->offset_to_next - 0x20) {
                next_size = IVALS(hbin->data, rel_offset+size);
                if (next_size > 0) {
                        size += next_size;
@@ -489,7 +496,7 @@ static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx,
 
        if (!hbin_get_tdr(regf, offset, nk,
                          (tdr_pull_fn_t)tdr_pull_nk_block, nk)) {
-               DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset));
+               DEBUG(0, ("Unable to find HBIN data for offset 0x%x\n", 
offset));
                return NULL;
        }
 
@@ -519,7 +526,8 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, struct 
hive_key *key,
 
        tmp = hbin_get(regf, private_data->nk->values_offset);
        if (!tmp.data) {
-               DEBUG(0, ("Unable to find value list\n"));
+               DEBUG(0, ("Unable to find value list at 0x%x\n",
+                               private_data->nk->values_offset));
                return WERR_GENERAL_FAILURE;
        }
 
@@ -534,7 +542,7 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, struct 
hive_key *key,
 
        if (!hbin_get_tdr(regf, vk_offset, vk,
                          (tdr_pull_fn_t)tdr_pull_vk_block, vk)) {
-               DEBUG(0, ("Unable to get VK block at %d\n", vk_offset));
+               DEBUG(0, ("Unable to get VK block at 0x%x\n", vk_offset));
                talloc_free(vk);
                return WERR_GENERAL_FAILURE;
        }
@@ -606,9 +614,15 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
        if (idx >= nk->num_subkeys)
                return WERR_NO_MORE_ITEMS;
 
+       /* Make sure that we don't crash if the key is empty */
+       if (nk->subkeys_offset == -1) {
+               return WERR_NO_MORE_ITEMS;
+       }
+
        data = hbin_get(private_data->hive, nk->subkeys_offset);
        if (!data.data) {
-               DEBUG(0, ("Unable to find subkey list\n"));
+               DEBUG(0, ("Unable to find subkey list at 0x%x\n",
+                       nk->subkeys_offset));
                return WERR_GENERAL_FAILURE;
        }
 
@@ -845,6 +859,11 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
        struct nk_block *nk = private_data->nk;
        uint32_t key_off = 0;
 
+       /* Make sure that we don't crash if the key is empty */
+       if (nk->subkeys_offset == -1) {
+               return WERR_BADFILE;
+       }
+
        data = hbin_get(private_data->hive, nk->subkeys_offset);
        if (!data.data) {
                DEBUG(0, ("Unable to find subkey list\n"));
@@ -1739,7 +1758,7 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct 
hive_key *parent,
 
        if (!hbin_get_tdr(regf, regf->header->data_offset, root,
                          (tdr_pull_fn_t)tdr_pull_nk_block, root)) {
-               DEBUG(0, ("Unable to find HBIN data for offset %d\n",
+               DEBUG(0, ("Unable to find HBIN data for offset 0x%x\n",
                        regf->header->data_offset));
                return WERR_GENERAL_FAILURE;
        }
@@ -1764,6 +1783,7 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct 
hive_key *parent,
 
        *ret = (struct hive_key *)regf_get_key(ctx, regf, offset);
 
+       DEBUG(9, ("Storing key %s\n", name));
        return regf_save_hbin(private_data->hive);
 }
 
@@ -1789,7 +1809,7 @@ static WERROR regf_set_value(struct hive_key *key, const 
char *name,
                        if (!hbin_get_tdr(regf, tmp_vk_offset, private_data,
                                          (tdr_pull_fn_t)tdr_pull_vk_block,
                                          &vk)) {
-                               DEBUG(0, ("Unable to get VK block at %d\n",
+                               DEBUG(0, ("Unable to get VK block at 0x%x\n",
                                        tmp_vk_offset));
                                return WERR_GENERAL_FAILURE;
                        }
diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl
index fd58ad2..064aaf0 100644
--- a/source4/lib/registry/regf.idl
+++ b/source4/lib/registry/regf.idl
@@ -74,8 +74,8 @@ interface regf
        };
 
        [noprint] enum reg_key_type { 
-               REG_ROOT_KEY = 0x20, 
-               REG_SUB_KEY  = 0x2C, 
+               REG_ROOT_KEY = 0x2C, 
+               REG_SUB_KEY  = 0x20, 
                REG_SYM_LINK = 0x10 
        };
 


-- 
Samba Shared Repository

Reply via email to