dartssh2 icon indicating copy to clipboard operation
dartssh2 copied to clipboard

sftp: FormatException: Unexpected extension byte (at offset 0)

Open holobeat opened this issue 2 years ago • 1 comments

The following code fails on stat or open. The sftp site is a site with public access. I am able to test the site access with FileZilla without any issues. The same behavior on both Linux and Windows.

import 'package:dartssh2/dartssh2.dart';

void main(List<String> args) async {
  final socket = await SSHSocket.connect('sftp.floridados.gov', 22);

  final client = SSHClient(
    socket,
    username: 'Public',
    onPasswordRequest: () => 'PubAccess1845!',
    onAuthenticated: () => print('*** Signed in'),
    printTrace: (msg) => print('TRACE: $msg'),
    printDebug: (msg) => print('DEBUG: $msg'),
  );

  final sftp = await client.sftp();
  print('*** Before calling stat');
  final stat = await sftp.stat('/');

  print(stat.size);
  print(stat.mode);

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

StackTrace:

Unhandled exception:
FormatException: Unexpected extension byte (at offset 0)
#0      _Utf8Decoder.convertSingle (dart:convert-patch/convert_patch.dart:1755:7)
#1      Utf8Decoder.convert (dart:convert/utf.dart:351:42)
#2      Utf8Codec.decode (dart:convert/utf.dart:63:20)
#3      SSHMessageReader.readUtf8 (package:dartssh2/src/ssh_message.dart:75:17)
#4      new SftpVersionPacket.decode (package:dartssh2/src/sftp/sftp_packet.dart:105:28)
#5      SftpClient._handleVersionPacket (package:dartssh2/src/sftp/sftp_client.dart:410:38)
#6      SftpClient._handlePacket (package:dartssh2/src/sftp/sftp_client.dart:392:16)
#7      SftpClient._handlePackets (package:dartssh2/src/sftp/sftp_client.dart:384:7)
#8      SftpClient._handleData (package:dartssh2/src/sftp/sftp_client.dart:374:5)
#9      _RootZone.runUnaryGuarded (dart:async/zone.dart:1618:10)
#10     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
#11     _DelayedData.perform (dart:async/stream_impl.dart:591:14)
#12     _StreamImplEvents.handleNext (dart:async/stream_impl.dart:706:11)
#13     _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:663:7)
#14     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#15     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
#16     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:122:13)
#17     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:193:5)

holobeat avatar Jul 08 '22 04:07 holobeat

Upon further examination, this appears not to be a bug of dartssh2. The error is probably caused by malformed UTF8 coming from the server. One solution would be updating SSHMessageReader class in ssh_message.dart to allow invalid or unterminated character sequences in utf8.decode(...). SSHMessageReader class uses top-level instance utf8, which has allowMalformed set to false by default.

holobeat avatar Jul 21 '22 02:07 holobeat

Adding allowMalformed to ssh_message.dart fixed it for me. Some of the legacy systems may be using Latin-1 codepage charset and this might be the workaround.

String readUtf8() {
  return utf8.decode(readString(), allowMalformed: true);
}

holobeat avatar Oct 20 '22 12:10 holobeat