Skip to content

Fix NullPointerException in getPortFromGetInfo when getInfo() fails - #197

Open
munzzyy wants to merge 1 commit into
guardianproject:masterfrom
munzzyy:fix-null-port-npe
Open

Fix NullPointerException in getPortFromGetInfo when getInfo() fails#197
munzzyy wants to merge 1 commit into
guardianproject:masterfrom
munzzyy:fix-null-port-npe

Conversation

@munzzyy

@munzzyy munzzyy commented Aug 9, 2026

Copy link
Copy Markdown

getPortFromGetInfo() can throw an uncaught NullPointerException.

getInfo(String) is documented as returning "the value or null on error", and it does return null whenever torControlConnection.getInfo(key) throws an IOException talking to the control port (it catches, logs, and falls through to return null). But getPortFromGetInfo() calls it and goes straight to value.trim() with no null check:

private int getPortFromGetInfo(String key) {
    var value = getInfo(key);
    if (value.trim().isEmpty()) return 0; // port is disabled
    return Integer.parseInt(value.substring(value.lastIndexOf(':') + 1, value.length() - 1));
}

It is called from controlPortThread right after authenticate():

socksPort = getPortFromGetInfo("net/listeners/socks");
httpTunnelPort = getPortFromGetInfo("net/listeners/httptunnel");

and that thread only catches IOException | ArrayIndexOutOfBoundsException | InterruptedException, not NPE. So any control-port hiccup during those two GETINFO calls (a dropped connection, a short read) makes getInfo() return null, and the null value.trim() becomes an uncaught NPE on that thread instead of the IOException path the method is clearly built to handle. An uncaught exception on any thread takes down the app process by default on Android.

The fix treats null the same as the empty case: the port just isn't available, return 0.

I verified it with a small standalone Java harness that runs the exact method body with value = null (what getInfo() returns on failure): before, it throws the NPE on String.trim(); after, same input returns 0, no exception. I don't have the Android SDK/NDK here, so I have not built the AAR or reproduced it on a device, this is a static read of the call chain plus a harness proof of the method logic. If you can confirm against a real control-port failure it would be worth a look.

getInfo() is documented to return null on error (IOException talking to
the control port), and its implementation does exactly that. But
getPortFromGetInfo() called value.trim() without checking for null
first, so any getInfo() failure while reading net/listeners/socks or
net/listeners/httptunnel threw an uncaught NullPointerException on
controlPortThread. That thread's catch block only lists IOException,
ArrayIndexOutOfBoundsException and InterruptedException, so the NPE
would propagate past it.

Treat a null value the same way an empty value is already treated:
the port is unavailable, return 0.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant