Foundation-Devices/tor

RangeError (RangeError: _readBytes has fewer bytes than expected.)

Opened this issue · 0 comments

To recreate this bug, we need to import socks5_proxy and tor:

import 'package:socks5_proxy/socks_client.dart';
import 'package:tor/tor.dart';

Assume we have these 2 code lines in function main:

  final int port = await startTor();
  final HttpClient httpClient = createProxyClient(port);

The functions startTor and createProxyClient are implemented as follows:

Future<int> startTor() async {
  await Tor.init();
  final DateTime t1 = DateTime.now();
  await Tor.instance.start();
  print('It took ${DateTime.now().difference(t1).inSeconds} seconds to connect Tor network.');
  return Tor.instance.port;
}

HttpClient createProxyClient(int port) {
  final httpClient = HttpClient();
  SocksTCPClient.assignToHttpClientWithSecureOptions(
    httpClient,
    [ProxySettings(InternetAddress.loopbackIPv4, port)],
    onBadCertificate: (X509Certificate certificate) {
      return true;
    },
  );
  return httpClient;
}

To use the httpClient variable, we have these 2 invocations in main:

  await accessInternetThroughTor(httpClient, destination: Uri.parse('https://icanhazip.com/'));
  await accessInternetThroughTor(httpClient, destination: Uri.parse('https://duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion/'));

The function accessInternetThroughTor is implemented as follows:

Future<void> accessInternetThroughTor(HttpClient httpClient, {required Uri destination}) async {
  final HttpClientRequest request = await httpClient.getUrl(destination); // FIXME: RangeError (RangeError: _readBytes has fewer bytes than expected.)
  final HttpClientResponse response = await request.close();
  print('STATUS: ${response.statusCode}\nRESPONSE: ${await utf8.decodeStream(response)}');
}

It looks like a legit way to use Tor proxy, but it will lead to RangeError (see the comment in accessInternetThroughTor above).

If we run an external Tor process in background listensing TCP port, say 9050, and we pass the port number to the createProxyClient invocation, all these codes work. No RangeError would appear. I've tried this on Linux, building the Flutter app as a Linux GUI application, and have this observation.

On Android the same error happens, if we use the port number returned from startTor ( See the code above).

I don't know it's a bug in package socks5_proxy or tor. When use an external Tor, all codes work. So it looks like a bug in package tor. On the other hand, the RangeError is thrown from package socks5_proxy.