[Zope3-checkins] SVN: Zope3/branches/ZopeX3-3.0/ Backported several DSN parser fixes including 304.

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Dec 9 15:57:17 EST 2004


Log message for revision 28611:
  Backported several DSN parser fixes including 304.
  

Changed:
  U   Zope3/branches/ZopeX3-3.0/doc/CHANGES.txt
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/__init__.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/interfaces.py
  U   Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/tests/test_dsnparser.py

-=-
Modified: Zope3/branches/ZopeX3-3.0/doc/CHANGES.txt
===================================================================
--- Zope3/branches/ZopeX3-3.0/doc/CHANGES.txt	2004-12-09 20:56:05 UTC (rev 28610)
+++ Zope3/branches/ZopeX3-3.0/doc/CHANGES.txt	2004-12-09 20:57:11 UTC (rev 28611)
@@ -6,6 +6,22 @@
 
   For information on future releases, see ROADMAP.txt.
 
+  Zope X3.0.1
+
+    Bug Fixes
+
+      - Backported several bug fixes made to the DSN parser, including issue
+        304.
+
+    Much thanks to everyone who contributed to this release:
+
+      Jim Fulton, Stephan Richter
+
+      Note: If you are not listed and contributed, please add yourself. This
+      note will be deleted before the release.
+
+  ------------------------------------------------------------------
+
   Zope X3.0.0
 
     New features
@@ -34,9 +50,6 @@
       Stephan Richter, Dmitry Vasiliev, Scott Pascoe, Bjorn Tillenius,
       Eckart Hertzler, Roger Ineichen, Stuart Bishop
 
-      Note: If you are not listed and contributed, please add yourself. This
-      note will be deleted before the release.
-
   ------------------------------------------------------------------
 
   Zope X3.0.0 Beta 2

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/__init__.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/__init__.py	2004-12-09 20:56:05 UTC (rev 28610)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/__init__.py	2004-12-09 20:57:11 UTC (rev 28611)
@@ -21,6 +21,7 @@
 """
 import types, string
 from types import StringTypes
+from urllib import unquote_plus
 
 from persistent import Persistent
 
@@ -171,11 +172,17 @@
 
        dbi://dbname
        dbi://dbname;param1=value...
+       dbi://user/dbname
        dbi://user:passwd/dbname
        dbi://user:passwd/dbname;param1=value...
+       dbi://user@host/dbname
+       dbi://user:passwd@host/dbname
        dbi://user:passwd@host:port/dbname
        dbi://user:passwd@host:port/dbname;param1=value...
 
+    Any values that might contain characters special for URIs need to be
+    quoted as it would be returned by `urllib.quote_plus`.
+
     Return value is a mapping with the following keys:
 
        username     username (if given) or an empty string
@@ -199,7 +206,9 @@
     dsn = raw_params[0]
     raw_params = raw_params[1:]
 
-    parameters = dict([param.split('=') for param in raw_params])
+    parameters = [param.split('=') for param in raw_params]
+    parameters = dict([(unquote_plus(key), unquote_plus(value))
+                       for key, value in parameters])
 
     result['parameters'] = parameters
 
@@ -210,12 +219,15 @@
         dbname = dsn
         dsn = ''
 
-    result['dbname'] = dbname
+    result['dbname'] = unquote_plus(dbname)
 
     # Get host and port from DSN
     if dsn and dsn.find('@') > 0:
         dsn, host_port = dsn.split('@')
-        host, port = host_port.split(':')
+        if host_port.find(':') > 0:
+            host, port = host_port.split(':')
+        else:
+            host, port = host_port, ''
     else:
         host, port = '', ''
 
@@ -224,12 +236,15 @@
 
     # Get username and password from DSN
     if dsn:
-        username, password = dsn.split(':', 1)
+        if dsn.find(':') > 0:
+            username, password = dsn.split(':', 1)
+        else:
+             username, password = dsn, ''
     else:
         username, password = '', ''
 
-    result['username'] = username
-    result['password'] = password
+    result['username'] = unquote_plus(username)
+    result['password'] = unquote_plus(password)
 
     return result
 

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/interfaces.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/interfaces.py	2004-12-09 20:56:05 UTC (rev 28610)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/interfaces.py	2004-12-09 20:57:11 UTC (rev 28611)
@@ -405,7 +405,9 @@
         "dbi://user:passwd/dbname\n"
         "dbi://user:passwd/dbname;param1=value...\n"
         "dbi://user:passwd@host:port/dbname\n"
-        "dbi://user:passwd@host:port/dbname;param1=value...\n"),
+        "dbi://user:passwd@host:port/dbname;param1=value...\n"
+        "\n"
+        "All values should be properlu URL-encoded."),
         default=u"dbi://dbname",
         required=True)
 

Modified: Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/tests/test_dsnparser.py
===================================================================
--- Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/tests/test_dsnparser.py	2004-12-09 20:56:05 UTC (rev 28610)
+++ Zope3/branches/ZopeX3-3.0/src/zope/app/rdb/tests/test_dsnparser.py	2004-12-09 20:57:11 UTC (rev 28611)
@@ -27,6 +27,12 @@
                   'password': '', 'host': '', 'port': ''}
         self.assertEqual(result, parseDSN(dsn))
 
+    def testDBNameWithSpecialCharacters(self):
+        dsn = 'dbi://test%2Fmore+'
+        result = {'parameters': {}, 'dbname': 'test/more ', 'username': '',
+                  'password': '', 'host': '', 'port': ''}
+        self.assertEqual(result, parseDSN(dsn))
+
     def testDBNameAndParams(self):
         dsn = 'dbi://test;param1=value1;param2=value2'
         result = {'parameters': {'param1': 'value1', 'param2': 'value2'},
@@ -34,12 +40,24 @@
                   'host': '', 'port': ''}
         self.assertEqual(result, parseDSN(dsn))
 
+    def testUser(self):
+        dsn = 'dbi://mike/test'
+        result = {'parameters': {}, 'dbname': 'test', 'username': 'mike',
+                  'password': '', 'host': '', 'port': ''}
+        self.assertEqual(result, parseDSN(dsn))
+
     def testUserPassword(self):
         dsn = 'dbi://mike:muster/test'
         result = {'parameters': {}, 'dbname': 'test', 'username': 'mike',
                   'password': 'muster', 'host': '', 'port': ''}
         self.assertEqual(result, parseDSN(dsn))
 
+    def testUserPasswordWithSpecialCharacters(self):
+        dsn = 'dbi://m+i+k+e:m%7Bu%7Dster/test'
+        result = {'parameters': {}, 'dbname': 'test', 'username': 'm i k e',
+                  'password': 'm{u}ster', 'host': '', 'port': ''}
+        self.assertEqual(result, parseDSN(dsn))
+
     def testPasswordWithColon(self):
         dsn = 'dbi://mike:before:after/test'
         result = {'parameters': {}, 'dbname': 'test', 'username': 'mike',
@@ -53,6 +71,25 @@
                   'host': '', 'port': ''}
         self.assertEqual(result, parseDSN(dsn))
 
+    def testParamsWithSpecialCharacters(self):
+        dsn = 'dbi://test;param%40=value%21;param%23=value%24'
+        result = {'parameters': {'param@': 'value!', 'param#': 'value$'},
+                  'dbname': 'test', 'username': '', 'password': '',
+                  'host': '', 'port': ''}
+        self.assertEqual(result, parseDSN(dsn))
+
+    def testUserAndHostWithoutPort(self):
+        dsn = 'dbi://mike@bohr/test'
+        result = {'parameters': {}, 'dbname': 'test', 'username': 'mike',
+                  'password': '', 'host': 'bohr', 'port': ''}
+        self.assertEqual(result, parseDSN(dsn))
+
+    def testUserPasswordAndHostWithoutPort(self):
+        dsn = 'dbi://mike:muster@bohr/test'
+        result = {'parameters': {}, 'dbname': 'test', 'username': 'mike',
+                  'password': 'muster', 'host': 'bohr', 'port': ''}
+        self.assertEqual(result, parseDSN(dsn))
+
     def testAllOptions(self):
         dsn = 'dbi://mike:muster@bohr:5432/test'
         result = {'parameters': {}, 'dbname': 'test', 'username': 'mike',



More information about the Zope3-Checkins mailing list