TerminalStudio / dartssh2

SSH and SFTP client written in pure Dart, aiming to be feature-rich as well as easy to use.
https://pub.dev/packages/dartssh2
MIT License
214 stars 58 forks source link

Killing the session results in an internal unhandled exception #17

Closed lmmfranco closed 2 years ago

lmmfranco commented 2 years ago

Example:

import 'dart:io';
import 'package:dartssh2/dartssh2.dart';

void main() async {
  var client = SSHClient(
    await SSHSocket.connect("192.168.0.1", 22),
    username: "root",
    onPasswordRequest: () => "mypass",
  );

  final session = await client.execute('sleep 10');
  stdout.addStream(session.stdout);
  stderr.addStream(session.stderr); 

  session.done.then((_) {
    print("session done");
    client.close();
  }).catchError((err) {
    print("session errored");
    client.close();
  });

  await Future.delayed(Duration(seconds: 2));
  session.kill(SSHSignal.INT);
}

Alternatively:

import 'dart:io';
import 'package:dartssh2/dartssh2.dart';

void main() async {
  var client = SSHClient(
    await SSHSocket.connect("192.168.0.1", 22),
    username: "root",
    onPasswordRequest: () => "mypass",
  );

  final session = await client.execute('sleep 10');
  stdout.addStream(session.stdout);
  stderr.addStream(session.stderr); 

  await Future.delayed(Duration(seconds: 2));
  session.kill(SSHSignal.INT);

  await session.done;
  client.close();
}

Will both result in this exception being thown:

Unhandled exception:
Null check operator used on a null value
#0      SSHSession._handleRequest (package:dartssh2/src/ssh_session.dart:119:41)
#1      SSHChannelController._handleRequestMessage (package:dartssh2/src/ssh_channel.dart:234:36)
#2      SSHChannelController.handleMessage (package:dartssh2/src/ssh_channel.dart:185:7)
#3      SSHClient._handleChannelRequest (package:dartssh2/src/ssh_client.dart:705:42)
#4      SSHClient._dispatchMessage (package:dartssh2/src/ssh_client.dart:489:16)
#5      SSHClient._onPacket (package:dartssh2/src/ssh_client.dart:432:7)
#6      SSHTransport._handleMessage (package:dartssh2/src/ssh_transport.dart:639:19)
#7      SSHTransport._processPackets (package:dartssh2/src/ssh_transport.dart:312:7)
#8      SSHTransport._processData (package:dartssh2/src/ssh_transport.dart:257:7)
#9      SSHTransport._onSocketData (package:dartssh2/src/ssh_transport.dart:235:7)
#10     _RootZone.runUnaryGuarded (dart:async/zone.dart:1620:10)
#11     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#12     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#13     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
#14     _StreamController._add (dart:async/stream_controller.dart:607:7)
#15     _StreamController.add (dart:async/stream_controller.dart:554:5)
#16     _Socket._onData (dart:io-patch/socket_patch.dart:2166:41)
#17     _RootZone.runUnaryGuarded (dart:async/zone.dart:1620:10)
#18     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#19     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
#20     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:733:19)
#21     _StreamController._add (dart:async/stream_controller.dart:607:7)
#22     _StreamController.add (dart:async/stream_controller.dart:554:5)
#23     new _RawSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1702:33)
#24     _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:1213:14)
#25     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#26     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
#27     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:120:13)
#28     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:185:5)

The problem also happens with shell.kill(), and won't happen if you dont use the .done promise

xtyxtyx commented 2 years ago

Thanks for reporting the issue! This has been fixed in 2.4.2.