Skip to content

Commit

Permalink
fix(mssql): escape special characters in passwords (#10437)
Browse files Browse the repository at this point in the history
## Description of changes
I found the error 
```
'IM002', '[IM002] [unixODBC][Driver Manager]Data source name not found and no default driver specified (0) (SQLDriverConnect)'
```
Because the password of mssql includes special characters like
`{R;3G1/8Al2AniRye` that start with `{` or include `;`.
It should be covered by `{` and `}` and replace `}` with`}}`.

Reference:
https://github.com/mkleehammer/pyodbc/wiki/Connecting-to-databases

https://stackoverflow.com/questions/78531086/pyodbc-connection-string-correctly-escaping-password-with-special-characters/78532507#78532507
  • Loading branch information
grieve54706 authored Nov 11, 2024
1 parent 4ea041f commit caf3632
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
6 changes: 5 additions & 1 deletion ibis/backends/mssql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,17 @@ def do_connect(
self.con = pyodbc.connect(
user=user,
server=f"{host},{port}",
password=password,
password=self._escape_special_characters(password),
driver=driver,
**kwargs,
)

self._post_connect()

@staticmethod
def _escape_special_characters(value: str) -> str:
return "{" + value.replace("}", "}}") + "}"

@util.experimental
@classmethod
def from_connection(cls, con: pyodbc.Connection) -> Backend:
Expand Down
11 changes: 11 additions & 0 deletions ibis/backends/mssql/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,14 @@ def test_create_temp_table(con, temp):
assert t.columns == ("a",)
finally:
con.drop_table(name)


def test_escape_special_characters():
test_func = ibis.backends.mssql.Backend._escape_special_characters
assert test_func("1bis_Testing!") == "{1bis_Testing!}"
assert test_func("{1bis_Testing!") == "{{1bis_Testing!}"
assert test_func("1bis_Testing!}") == "{1bis_Testing!}}}"
assert test_func("{1bis_Testing!}") == "{{1bis_Testing!}}}"
assert test_func("1bis}Testing!") == "{1bis}}Testing!}"
assert test_func("{R;3G1/8Al2AniRye") == "{{R;3G1/8Al2AniRye}"
assert test_func("{R;3G1/8Al2AniRye}") == "{{R;3G1/8Al2AniRye}}}"

0 comments on commit caf3632

Please sign in to comment.