Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit effad53

Browse files
author
Chris Board
committed
Stability improvements and improvements to larger result sets
Stability improvements due to timing issues that could potentially cause a crash. Fixed issues where if there is a large resultset being returned would potentially receive an unexpected packet in between which meant passing connection data would go wrong and cause an index out of bounds exception.
1 parent 9adc18f commit effad53

File tree

14 files changed

+475
-244
lines changed

14 files changed

+475
-244
lines changed
0 Bytes
Binary file not shown.

.idea/caches/gradle_models.ser

2.78 KB
Binary file not shown.

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

AndroidMySQLConnector/build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ else
2020
}
2121

2222
archivesBaseName="AndroidMySQLConnector"
23-
version '0.34'
23+
version '0.35'
2424
group 'com.BoardiesITSolutions'
2525

2626

@@ -30,8 +30,8 @@ android {
3030
//applicationId "com.BoardiesITSolutions.AndroidMySQLConnector"
3131
minSdkVersion 19
3232
targetSdkVersion 29
33-
versionCode 24
34-
versionName "0.34"
33+
versionCode 25
34+
versionName "0.35"
3535
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
3636
}
3737
buildTypes {
@@ -90,4 +90,5 @@ def getArtifactFullPath() {
9090
dependencies {
9191
implementation fileTree(dir: 'libs', include: ['*.jar'])
9292
implementation 'androidx.appcompat:appcompat:1.1.0'
93+
implementation("com.google.guava:guava:28.2-android")
9394
}

AndroidMySQLConnector/src/main/java/com/BoardiesITSolutions/AndroidMySQLConnector/Connection.java

Lines changed: 77 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ public class Connection
8383
public static final int CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS = 0x00400000;
8484
public static final int CLIENT_SESSION_TRACK = 0x00800000;
8585

86+
87+
public static final int MULTI_RESULTS = 1 << 17;
88+
public static final int DEPRECATE_EOF = 1 << 24;
8689
public static final int CLIENT_OPTIONAL_RESULTSET_METADATA = 1 << 25;
8790

8891
//Character Sets
@@ -394,6 +397,9 @@ private void processWelcomePacket() throws MySQLConnException, IOException {
394397

395398
}
396399

400+
clientCapabilities &= ~DEPRECATE_EOF;
401+
clientCapabilities &= ~MULTI_RESULTS;
402+
397403
//Check if the server is set to don't allow database.table, if so unset it so we can
398404
//Having this enabled means SHOW TABLES and SHOW DATABASES can't be executed as it will only
399405
//use the database that we are connected to
@@ -614,106 +620,94 @@ private void sendAuthResponse()
614620
@Override
615621
public void socketDataSent()
616622
{
617-
Log.d("Connection", "Socket Data Sent");
618-
try {
619-
Helpers.MYSQL_PACKET_TYPE mysqlPacketType = Helpers.getMySQLPacketType(Connection.this.mysqlIO.getSocketByteArray());
620-
if (mysqlPacketType == Helpers.MYSQL_PACKET_TYPE.MYSQL_ERROR_PACKET) {
621-
MySQLErrorPacket mySQLErrorPacket = new MySQLErrorPacket(Connection.this);
622-
//We can't do anything else here, so throw a MySQLConnException
623-
624-
final MySQLConnException connException = new MySQLConnException(mySQLErrorPacket.getErrorMsg(), mySQLErrorPacket.getErrorCode(), mySQLErrorPacket.getSqlState());
625-
if (getReturnCallbackToMainThread())
626-
{
627-
getActivity().runOnUiThread(new Runnable()
628-
{
629-
@Override
630-
public void run()
631-
{
632-
iConnectionInterface.handleMySQLConnException(connException);
633-
}
634-
});
623+
synchronized (mysqlIO.getConnection()) {
624+
Log.d("Connection", "Socket Data Sent");
625+
try {
626+
Helpers.MYSQL_PACKET_TYPE mysqlPacketType = Helpers.getMySQLPacketType(Connection.this.mysqlIO.getSocketByteArray());
627+
if (mysqlPacketType == Helpers.MYSQL_PACKET_TYPE.MYSQL_ERROR_PACKET) {
628+
MySQLErrorPacket mySQLErrorPacket = new MySQLErrorPacket(Connection.this);
629+
//We can't do anything else here, so throw a MySQLConnException
630+
631+
final MySQLConnException connException = new MySQLConnException(mySQLErrorPacket.getErrorMsg(), mySQLErrorPacket.getErrorCode(), mySQLErrorPacket.getSqlState());
632+
if (getReturnCallbackToMainThread()) {
633+
getActivity().runOnUiThread(new Runnable() {
634+
@Override
635+
public void run()
636+
{
637+
iConnectionInterface.handleMySQLConnException(connException);
638+
}
639+
});
640+
}
641+
else {
642+
iConnectionInterface.handleMySQLConnException(connException);
643+
}
635644
}
636-
else
637-
{
638-
iConnectionInterface.handleMySQLConnException(connException);
645+
else if (mysqlPacketType == Helpers.MYSQL_PACKET_TYPE.MYSQL_OK_PACKET) {
646+
MySQLOKPacket mySQLOKPacket = new MySQLOKPacket(Connection.this);
647+
if (getReturnCallbackToMainThread()) {
648+
getActivity().runOnUiThread(new Runnable() {
649+
@Override
650+
public void run()
651+
{
652+
Connection.this.mysqlIO.setIsDBConnected(true);
653+
iConnectionInterface.actionCompleted();
654+
}
655+
});
656+
}
657+
else {
658+
Connection.this.mysqlIO.setIsDBConnected(true);
659+
iConnectionInterface.actionCompleted();
660+
}
661+
}
662+
else if (mysqlPacketType == Helpers.MYSQL_PACKET_TYPE.MYSQL_EOF_PACKET) {
663+
MySQLOKPacket mySQLOKPacket = new MySQLOKPacket(Connection.this);
664+
if (getReturnCallbackToMainThread()) {
665+
getActivity().runOnUiThread(new Runnable() {
666+
@Override
667+
public void run()
668+
{
669+
Connection.this.mysqlIO.setIsDBConnected(true);
670+
iConnectionInterface.actionCompleted();
671+
}
672+
});
673+
}
674+
else {
675+
Connection.this.mysqlIO.setIsDBConnected(true);
676+
iConnectionInterface.actionCompleted();
677+
}
639678
}
640679
}
641-
else if (mysqlPacketType == Helpers.MYSQL_PACKET_TYPE.MYSQL_OK_PACKET) {
642-
MySQLOKPacket mySQLOKPacket = new MySQLOKPacket(Connection.this);
643-
if (getReturnCallbackToMainThread())
644-
{
645-
getActivity().runOnUiThread(new Runnable()
646-
{
680+
catch (final IOException ex) {
681+
Log.e("MySQLConnection", ex.toString());
682+
if (getReturnCallbackToMainThread()) {
683+
getActivity().runOnUiThread(new Runnable() {
647684
@Override
648685
public void run()
649686
{
650-
iConnectionInterface.actionCompleted();
687+
iConnectionInterface.handleIOException(ex);
651688
}
652689
});
653690
}
654-
else
655-
{
656-
iConnectionInterface.actionCompleted();
691+
else {
692+
iConnectionInterface.handleIOException(ex);
657693
}
658694
}
659-
else if (mysqlPacketType == Helpers.MYSQL_PACKET_TYPE.MYSQL_EOF_PACKET)
660-
{
661-
MySQLOKPacket mySQLOKPacket = new MySQLOKPacket(Connection.this);
662-
if (getReturnCallbackToMainThread())
663-
{
664-
getActivity().runOnUiThread(new Runnable()
665-
{
695+
catch (final InvalidSQLPacketException ex) {
696+
Log.e("MySQLConnection", ex.toString());
697+
if (getReturnCallbackToMainThread()) {
698+
getActivity().runOnUiThread(new Runnable() {
666699
@Override
667700
public void run()
668701
{
669-
iConnectionInterface.actionCompleted();
702+
iConnectionInterface.handleInvalidSQLPacketException(ex);
670703
}
671704
});
672705
}
673-
else
674-
{
675-
iConnectionInterface.actionCompleted();
706+
else {
707+
iConnectionInterface.handleInvalidSQLPacketException(ex);
676708
}
677709
}
678710
}
679-
catch (final IOException ex)
680-
{
681-
Log.e("MySQLConnection", ex.toString());
682-
if (getReturnCallbackToMainThread())
683-
{
684-
getActivity().runOnUiThread(new Runnable()
685-
{
686-
@Override
687-
public void run()
688-
{
689-
iConnectionInterface.handleIOException(ex);
690-
}
691-
});
692-
}
693-
else
694-
{
695-
iConnectionInterface.handleIOException(ex);
696-
}
697-
}
698-
catch (final InvalidSQLPacketException ex)
699-
{
700-
Log.e("MySQLConnection", ex.toString());
701-
if (getReturnCallbackToMainThread())
702-
{
703-
getActivity().runOnUiThread(new Runnable()
704-
{
705-
@Override
706-
public void run()
707-
{
708-
iConnectionInterface.handleInvalidSQLPacketException(ex);
709-
}
710-
});
711-
}
712-
else
713-
{
714-
iConnectionInterface.handleInvalidSQLPacketException(ex);
715-
}
716-
}
717711
}
718712

719713
@Override
@@ -810,7 +804,9 @@ public static String toString(byte[] value, int offset, int length) {
810804

811805
public Statement createStatement()
812806
{
813-
return new Statement(this);
807+
synchronized (this.mysqlIO.getConnection()) {
808+
return new Statement(this);
809+
}
814810
}
815811

816812
private void parseVersionNumber()

AndroidMySQLConnector/src/main/java/com/BoardiesITSolutions/AndroidMySQLConnector/Helpers.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,35 @@ else if ((packetType & 0xfe) == 0xfe)
5252
{
5353
return MYSQL_PACKET_TYPE.MYSQL_EOF_PACKET;
5454
}
55-
else
55+
else if (packetType == 0x00)
5656
{
5757
return MYSQL_PACKET_TYPE.MYSQL_OK_PACKET;
5858
}
59+
else
60+
{
61+
//If its unknwon packet then we probably at this point don't care
62+
//as we're not in the right place to check the packet type and should just
63+
//continue what data is available
64+
return MYSQL_PACKET_TYPE.MYSQL_UNKNOWN_PACKET;
65+
}
66+
}
67+
68+
/**
69+
* Checks whether its possible that we have an EOF packet. You sometimes can get an EOF looking
70+
* packet when its actually a Length Encoded Integer. So check the socket length to determine
71+
* if this is a true EOF packet
72+
* @param mySQLIO
73+
* @return
74+
*/
75+
public static boolean checkIfRealEOFPacket(MySQLIO mySQLIO)
76+
{
77+
if ((mySQLIO.getSocketDataLength() - mySQLIO.getCurrentBytesRead()) < 9)
78+
{
79+
return true;
80+
}
81+
else
82+
{
83+
return false;
84+
}
5985
}
6086
}

0 commit comments

Comments
 (0)