Revert error packet parsing changes (#508)

Revert the changes made in commit 02910b7 to the mysql error packet
parsing, as it didn't take the CLIENT_PROTOCOL_41 case into account.

It appears that the non-CLIENT_PROTOCOL_41 case was off by one as well
(sliced data on 4 vs 3).

I also added two new tests to cover those cases.

See: https://dev.mysql.com/doc/internals/en/packet-ERR_Packet.html
This commit is contained in:
diana
2016-08-31 22:06:58 -04:00
committed by INADA Naoki
parent 7d97090951
commit 73e88b8041
3 changed files with 28 additions and 1 deletions

View File

@@ -97,6 +97,11 @@ del _map_error, ER
def raise_mysql_exception(data):
errno = struct.unpack('<h', data[1:3])[0]
errval = data[4:].decode('utf-8', 'replace')
is_41 = data[3:4] == b"#"
if is_41:
# client protocol 4.1
errval = data[9:].decode('utf-8', 'replace')
else:
errval = data[3:].decode('utf-8', 'replace')
errorclass = error_map.get(errno, InternalError)
raise errorclass(errno, errval)

View File

@@ -5,6 +5,7 @@ from pymysql.tests.test_basic import *
from pymysql.tests.test_connection import *
from pymysql.tests.test_converters import *
from pymysql.tests.test_cursor import *
from pymysql.tests.test_err import *
from pymysql.tests.test_issues import *
from pymysql.tests.test_load_local import *
from pymysql.tests.test_nextset import *

21
pymysql/tests/test_err.py Normal file
View File

@@ -0,0 +1,21 @@
import unittest2
from pymysql import err
__all__ = ["TestRaiseException"]
class TestRaiseException(unittest2.TestCase):
def test_raise_mysql_exception(self):
data = b"\xff\x15\x04Access denied"
with self.assertRaises(err.OperationalError) as cm:
err.raise_mysql_exception(data)
self.assertEqual(cm.exception.args, (1045, 'Access denied'))
def test_raise_mysql_exception_client_protocol_41(self):
data = b"\xff\x15\x04#28000Access denied"
with self.assertRaises(err.OperationalError) as cm:
err.raise_mysql_exception(data)
self.assertEqual(cm.exception.args, (1045, 'Access denied'))