[SCM] Samba Shared Repository - branch master updated
Jelmer Vernooij
jelmer at samba.org
Sun Sep 19 13:35:03 MDT 2010
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 <jelmer at 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: wilco at baanhofman.nl <wilco at 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 <jelmer at samba.org>
commit 7efcb3ca66b12972de3707164c7bd415619a4bb8
Author: wilco at baanhofman.nl <wilco at 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 <jelmer at samba.org>
commit d0cef92532f7c943e1c70d49ed96f090235b928e
Author: wilco at baanhofman.nl <wilco at 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 <jelmer at samba.org>
commit 2c3f56098b0322db2e74e860a0f236fde9f74bbc
Author: wilco at baanhofman.nl <wilco at 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 <jelmer at 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 <jelmer at samba.org> 2008
+ Copyright (C) Wilco Baan Hofman <wilco at 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
More information about the samba-cvs
mailing list