Fix NPE when sending DatagramPacket
This is due to code after
getImpl().connect(address, port);
is not executed if it throws exception, leaving DatagramPacket in an
inconsistant state.
Re-arrange the order of code so that the state is now consistent.
Bug: 31218085
Bug: 31495962
(cherry-picked from commit 6764aa32a4b66a3c589f4a00615a1e36d87f308f)
Test: libcore.java.net.DatagramSocketTest
Change-Id: Iab9bfd9af211666564e49de62fdae964d6330daf
diff --git a/luni/src/test/java/libcore/java/net/DatagramSocketTest.java b/luni/src/test/java/libcore/java/net/DatagramSocketTest.java
index 86e47ec..067291a 100644
--- a/luni/src/test/java/libcore/java/net/DatagramSocketTest.java
+++ b/luni/src/test/java/libcore/java/net/DatagramSocketTest.java
@@ -18,8 +18,11 @@
import junit.framework.TestCase;
+import java.lang.reflect.Field;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
+import java.net.DatagramSocketImpl;
+import java.net.InetAddress;
public class DatagramSocketTest extends TestCase {
@@ -55,4 +58,21 @@
assertEquals(-1, ds.getLocalPort());
assertNull(ds.getLocalSocketAddress());
}
+ // Socket should become connected even if impl.connect() failed and threw exception.
+ public void test_b31218085() throws Exception {
+ final int port = 9999;
+
+ try (DatagramSocket s = new DatagramSocket()) {
+ // Set fd of DatagramSocket to null, forcing impl.connect() to throw.
+ Field f = DatagramSocket.class.getDeclaredField("impl");
+ f.setAccessible(true);
+ DatagramSocketImpl impl = (DatagramSocketImpl) f.get(s);
+ f = DatagramSocketImpl.class.getDeclaredField("fd");
+ f.setAccessible(true);
+ f.set(impl, null);
+
+ s.connect(InetAddress.getLocalHost(), port);
+ assertTrue(s.isConnected());
+ }
+ }
}
diff --git a/ojluni/src/main/java/java/net/DatagramSocket.java b/ojluni/src/main/java/java/net/DatagramSocket.java
index 966f30f..d089b89 100755
--- a/ojluni/src/main/java/java/net/DatagramSocket.java
+++ b/ojluni/src/main/java/java/net/DatagramSocket.java
@@ -162,10 +162,12 @@
// connection will be emulated by DatagramSocket
connectState = ST_CONNECTED_NO_IMPL;
}*/
- getImpl().connect(address, port);
// socket is now connected by the impl
connectState = ST_CONNECTED;
+
+ getImpl().connect(address, port);
+
// ----- END android -----
}