class OldConfigOptionError(Exception):
pass
+class UnescapedHashError(Exception):
+ def __str__(self):
+ return ("The configuration entry %s contained an unescaped '#' character."
+ % quote_output(self.args[0]))
+
class Node(service.MultiService):
# this implements common functionality of both Client nodes and Introducer
test_name = tempfile.mktemp()
_assert(os.path.dirname(test_name) == tempdir, test_name, tempdir)
+ @staticmethod
+ def _contains_unescaped_hash(item):
+ characters = iter(item)
+ for c in characters:
+ if c == '\\':
+ characters.next()
+ elif c == '#':
+ return True
+
+ return False
+
def get_config(self, section, option, default=_None, boolean=False):
try:
if boolean:
return self.config.getboolean(section, option)
- return self.config.get(section, option)
+
+ item = self.config.get(section, option)
+ if option.endswith(".furl") and self._contains_unescaped_hash(item):
+ raise UnescapedHashError(item)
+
+ return item
except (ConfigParser.NoOptionError, ConfigParser.NoSectionError):
if default is _None:
fn = os.path.join(self.basedir, u"tahoe.cfg")
from twisted.application import service
import allmydata
-from allmydata.node import OldConfigError, OldConfigOptionError, MissingConfigEntry
+from allmydata.node import Node, OldConfigError, OldConfigOptionError, MissingConfigEntry, UnescapedHashError
from allmydata import client
from allmydata.storage_client import StorageFarmBroker
from allmydata.util import base32, fileutil
BASECONFIG)
client.Client(basedir)
+ def test_comment(self):
+ dummy = "pb://wl74cyahejagspqgy4x5ukrvfnevlknt@127.0.0.1:58889/bogus"
+
+ should_fail = [r"test#test", r"#testtest", r"test\\#test"]
+ should_not_fail = [r"test\#test", r"test\\\#test", r"testtest"]
+
+ basedir = "test_client.Basic.test_comment"
+ os.mkdir(basedir)
+
+ def write_config(shouldfail, s):
+ config = ("[client]\n"
+ "introducer.furl = %s\n" % s)
+ fileutil.write(os.path.join(basedir, "tahoe.cfg"), config)
+
+ for s in should_fail:
+ self.failUnless(Node._contains_unescaped_hash(s))
+ write_config(s)
+ self.failUnlessRaises(UnescapedHashError, client.Client, basedir)
+
+ for s in should_not_fail:
+ self.failIf(Node._contains_unescaped_hash(s))
+ write_config(s)
+ client.Client(basedir)
+
+
@mock.patch('twisted.python.log.msg')
def test_error_on_old_config_files(self, mock_log_msg):
basedir = "test_client.Basic.test_error_on_old_config_files"
u"\u2621"))
return d
+ def test_tahoe_cfg_hash_in_name(self):
+ basedir = "test_node/test_cfg_hash_in_name"
+ nickname = "Hash#Bang!" # a clever nickname containing a hash
+ fileutil.make_dirs(basedir)
+ f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
+ f.write("[node]\n")
+ f.write("nickname = %s\n" % (nickname,))
+ f.close()
+ n = TestNode(basedir)
+ self.failUnless(n.nickname == nickname)
+
def test_private_config(self):
basedir = "test_node/test_private_config"
privdir = os.path.join(basedir, "private")