@electerm/ssh2 1.17.2 → 1.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -244,6 +244,8 @@ class Client extends EventEmitter {
244
244
  ? cfg.debug
245
245
  : undefined);
246
246
 
247
+ this.config.sftpEncoding = cfg.sftpEncoding || 'utf8';
248
+
247
249
  if (cfg.agentForward === true && !this.config.allowAgentFwd) {
248
250
  throw new Error(
249
251
  'You must set a valid agent path to allow agent forwarding'
@@ -604,7 +606,7 @@ class Client extends EventEmitter {
604
606
  };
605
607
  const instance = (
606
608
  isSFTP
607
- ? new SFTP(this, chanInfo, { debug })
609
+ ? new SFTP(this, chanInfo, { debug, encoding: this.config.sftpEncoding })
608
610
  : new Channel(this, chanInfo)
609
611
  );
610
612
  this._chanMgr.update(info.recipient, instance);
@@ -8,6 +8,7 @@ const {
8
8
  Writable: WritableStream
9
9
  } = require('stream');
10
10
  const { inherits, types: { isDate } } = require('util');
11
+ const iconv = require('iconv-lite');
11
12
 
12
13
  const FastBuffer = Buffer[Symbol.species];
13
14
 
@@ -147,6 +148,7 @@ class SFTP extends EventEmitter {
147
148
  this._version = -1;
148
149
  this._extensions = {};
149
150
  this._biOpt = cfg.biOpt;
151
+ this._encoding = cfg.encoding || 'utf8';
150
152
  this._pktLenBytes = 0;
151
153
  this._pktLen = 0;
152
154
  this._pktPos = 0;
@@ -339,7 +341,8 @@ class SFTP extends EventEmitter {
339
341
  uint32 pflags
340
342
  ATTRS attrs
341
343
  */
342
- const pathLen = Buffer.byteLength(path);
344
+ const pathBuf = iconv.encode(path, this._encoding);
345
+ const pathLen = pathBuf.length;
343
346
  let p = 9;
344
347
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen + 4 + 4 + attrsLen);
345
348
 
@@ -349,7 +352,7 @@ class SFTP extends EventEmitter {
349
352
  writeUInt32BE(buf, reqid, 5);
350
353
 
351
354
  writeUInt32BE(buf, pathLen, p);
352
- buf.utf8Write(path, p += 4, pathLen);
355
+ buf.set(pathBuf, p += 4);
353
356
  writeUInt32BE(buf, flags, p += pathLen);
354
357
  writeUInt32BE(buf, attrsFlags, p += 4);
355
358
  if (attrsLen) {
@@ -734,7 +737,8 @@ class SFTP extends EventEmitter {
734
737
  uint32 id
735
738
  string filename
736
739
  */
737
- const fnameLen = Buffer.byteLength(filename);
740
+ const fnameBuf = iconv.encode(filename, this._encoding);
741
+ const fnameLen = fnameBuf.length;
738
742
  let p = 9;
739
743
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + fnameLen);
740
744
 
@@ -744,7 +748,7 @@ class SFTP extends EventEmitter {
744
748
  writeUInt32BE(buf, reqid, 5);
745
749
 
746
750
  writeUInt32BE(buf, fnameLen, p);
747
- buf.utf8Write(filename, p += 4, fnameLen);
751
+ buf.set(fnameBuf, p += 4);
748
752
 
749
753
  this._requests[reqid] = { cb };
750
754
 
@@ -762,8 +766,10 @@ class SFTP extends EventEmitter {
762
766
  string oldpath
763
767
  string newpath
764
768
  */
765
- const oldLen = Buffer.byteLength(oldPath);
766
- const newLen = Buffer.byteLength(newPath);
769
+ const oldBuf = iconv.encode(oldPath, this._encoding);
770
+ const newBuf = iconv.encode(newPath, this._encoding);
771
+ const oldLen = oldBuf.length;
772
+ const newLen = newBuf.length;
767
773
  let p = 9;
768
774
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + oldLen + 4 + newLen);
769
775
 
@@ -773,9 +779,9 @@ class SFTP extends EventEmitter {
773
779
  writeUInt32BE(buf, reqid, 5);
774
780
 
775
781
  writeUInt32BE(buf, oldLen, p);
776
- buf.utf8Write(oldPath, p += 4, oldLen);
782
+ buf.set(oldBuf, p += 4);
777
783
  writeUInt32BE(buf, newLen, p += oldLen);
778
- buf.utf8Write(newPath, p += 4, newLen);
784
+ buf.set(newBuf, p += 4);
779
785
 
780
786
  this._requests[reqid] = { cb };
781
787
 
@@ -806,7 +812,8 @@ class SFTP extends EventEmitter {
806
812
  string path
807
813
  ATTRS attrs
808
814
  */
809
- const pathLen = Buffer.byteLength(path);
815
+ const pathBuf = iconv.encode(path, this._encoding);
816
+ const pathLen = pathBuf.length;
810
817
  let p = 9;
811
818
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen + 4 + attrsLen);
812
819
 
@@ -816,7 +823,7 @@ class SFTP extends EventEmitter {
816
823
  writeUInt32BE(buf, reqid, 5);
817
824
 
818
825
  writeUInt32BE(buf, pathLen, p);
819
- buf.utf8Write(path, p += 4, pathLen);
826
+ buf.set(pathBuf, p += 4);
820
827
  writeUInt32BE(buf, flags, p += pathLen);
821
828
  if (attrsLen) {
822
829
  p += 4;
@@ -844,7 +851,8 @@ class SFTP extends EventEmitter {
844
851
  uint32 id
845
852
  string path
846
853
  */
847
- const pathLen = Buffer.byteLength(path);
854
+ const pathBuf = iconv.encode(path, this._encoding);
855
+ const pathLen = pathBuf.length;
848
856
  let p = 9;
849
857
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
850
858
 
@@ -854,7 +862,7 @@ class SFTP extends EventEmitter {
854
862
  writeUInt32BE(buf, reqid, 5);
855
863
 
856
864
  writeUInt32BE(buf, pathLen, p);
857
- buf.utf8Write(path, p += 4, pathLen);
865
+ buf.set(pathBuf, p += 4);
858
866
 
859
867
  this._requests[reqid] = { cb };
860
868
 
@@ -987,7 +995,8 @@ class SFTP extends EventEmitter {
987
995
  uint32 id
988
996
  string path
989
997
  */
990
- const pathLen = Buffer.byteLength(path);
998
+ const pathBuf = iconv.encode(path, this._encoding);
999
+ const pathLen = pathBuf.length;
991
1000
  let p = 9;
992
1001
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
993
1002
 
@@ -997,7 +1006,7 @@ class SFTP extends EventEmitter {
997
1006
  writeUInt32BE(buf, reqid, 5);
998
1007
 
999
1008
  writeUInt32BE(buf, pathLen, p);
1000
- buf.utf8Write(path, p += 4, pathLen);
1009
+ buf.set(pathBuf, p += 4);
1001
1010
 
1002
1011
  this._requests[reqid] = { cb };
1003
1012
 
@@ -1014,7 +1023,8 @@ class SFTP extends EventEmitter {
1014
1023
  uint32 id
1015
1024
  string path
1016
1025
  */
1017
- const pathLen = Buffer.byteLength(path);
1026
+ const pathBuf = iconv.encode(path, this._encoding);
1027
+ const pathLen = pathBuf.length;
1018
1028
  let p = 9;
1019
1029
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
1020
1030
 
@@ -1024,7 +1034,7 @@ class SFTP extends EventEmitter {
1024
1034
  writeUInt32BE(buf, reqid, 5);
1025
1035
 
1026
1036
  writeUInt32BE(buf, pathLen, p);
1027
- buf.utf8Write(path, p += 4, pathLen);
1037
+ buf.set(pathBuf, p += 4);
1028
1038
 
1029
1039
  this._requests[reqid] = { cb };
1030
1040
 
@@ -1041,7 +1051,8 @@ class SFTP extends EventEmitter {
1041
1051
  uint32 id
1042
1052
  string path
1043
1053
  */
1044
- const pathLen = Buffer.byteLength(path);
1054
+ const pathBuf = iconv.encode(path, this._encoding);
1055
+ const pathLen = pathBuf.length;
1045
1056
  let p = 9;
1046
1057
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
1047
1058
 
@@ -1051,7 +1062,7 @@ class SFTP extends EventEmitter {
1051
1062
  writeUInt32BE(buf, reqid, 5);
1052
1063
 
1053
1064
  writeUInt32BE(buf, pathLen, p);
1054
- buf.utf8Write(path, p += 4, pathLen);
1065
+ buf.set(pathBuf, p += 4);
1055
1066
 
1056
1067
  this._requests[reqid] = { cb };
1057
1068
 
@@ -1080,7 +1091,8 @@ class SFTP extends EventEmitter {
1080
1091
  string path
1081
1092
  ATTRS attrs
1082
1093
  */
1083
- const pathLen = Buffer.byteLength(path);
1094
+ const pathBuf = iconv.encode(path, this._encoding);
1095
+ const pathLen = pathBuf.length;
1084
1096
  let p = 9;
1085
1097
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen + 4 + attrsLen);
1086
1098
 
@@ -1090,7 +1102,7 @@ class SFTP extends EventEmitter {
1090
1102
  writeUInt32BE(buf, reqid, 5);
1091
1103
 
1092
1104
  writeUInt32BE(buf, pathLen, p);
1093
- buf.utf8Write(path, p += 4, pathLen);
1105
+ buf.set(pathBuf, p += 4);
1094
1106
  writeUInt32BE(buf, flags, p += pathLen);
1095
1107
  if (attrsLen) {
1096
1108
  p += 4;
@@ -1205,7 +1217,8 @@ class SFTP extends EventEmitter {
1205
1217
  uint32 id
1206
1218
  string path
1207
1219
  */
1208
- const pathLen = Buffer.byteLength(path);
1220
+ const pathBuf = iconv.encode(path, this._encoding);
1221
+ const pathLen = pathBuf.length;
1209
1222
  let p = 9;
1210
1223
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
1211
1224
 
@@ -1215,7 +1228,7 @@ class SFTP extends EventEmitter {
1215
1228
  writeUInt32BE(buf, reqid, 5);
1216
1229
 
1217
1230
  writeUInt32BE(buf, pathLen, p);
1218
- buf.utf8Write(path, p += 4, pathLen);
1231
+ buf.set(pathBuf, p += 4);
1219
1232
 
1220
1233
  this._requests[reqid] = {
1221
1234
  cb: (err, names) => {
@@ -1243,8 +1256,10 @@ class SFTP extends EventEmitter {
1243
1256
  string linkpath
1244
1257
  string targetpath
1245
1258
  */
1246
- const linkLen = Buffer.byteLength(linkPath);
1247
- const targetLen = Buffer.byteLength(targetPath);
1259
+ const linkBuf = iconv.encode(linkPath, this._encoding);
1260
+ const targetBuf = iconv.encode(targetPath, this._encoding);
1261
+ const linkLen = linkBuf.length;
1262
+ const targetLen = targetBuf.length;
1248
1263
  let p = 9;
1249
1264
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + linkLen + 4 + targetLen);
1250
1265
 
@@ -1256,14 +1271,14 @@ class SFTP extends EventEmitter {
1256
1271
  if (this._isOpenSSH) {
1257
1272
  // OpenSSH has linkpath and targetpath positions switched
1258
1273
  writeUInt32BE(buf, targetLen, p);
1259
- buf.utf8Write(targetPath, p += 4, targetLen);
1274
+ buf.set(targetBuf, p += 4);
1260
1275
  writeUInt32BE(buf, linkLen, p += targetLen);
1261
- buf.utf8Write(linkPath, p += 4, linkLen);
1276
+ buf.set(linkBuf, p += 4);
1262
1277
  } else {
1263
1278
  writeUInt32BE(buf, linkLen, p);
1264
- buf.utf8Write(linkPath, p += 4, linkLen);
1279
+ buf.set(linkBuf, p += 4);
1265
1280
  writeUInt32BE(buf, targetLen, p += linkLen);
1266
- buf.utf8Write(targetPath, p += 4, targetLen);
1281
+ buf.set(targetBuf, p += 4);
1267
1282
  }
1268
1283
 
1269
1284
  this._requests[reqid] = { cb };
@@ -1281,7 +1296,8 @@ class SFTP extends EventEmitter {
1281
1296
  uint32 id
1282
1297
  string path
1283
1298
  */
1284
- const pathLen = Buffer.byteLength(path);
1299
+ const pathBuf = iconv.encode(path, this._encoding);
1300
+ const pathLen = pathBuf.length;
1285
1301
  let p = 9;
1286
1302
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + pathLen);
1287
1303
 
@@ -1291,7 +1307,7 @@ class SFTP extends EventEmitter {
1291
1307
  writeUInt32BE(buf, reqid, 5);
1292
1308
 
1293
1309
  writeUInt32BE(buf, pathLen, p);
1294
- buf.utf8Write(path, p += 4, pathLen);
1310
+ buf.set(pathBuf, p += 4);
1295
1311
 
1296
1312
  this._requests[reqid] = {
1297
1313
  cb: (err, names) => {
@@ -1325,8 +1341,10 @@ class SFTP extends EventEmitter {
1325
1341
  string oldpath
1326
1342
  string newpath
1327
1343
  */
1328
- const oldLen = Buffer.byteLength(oldPath);
1329
- const newLen = Buffer.byteLength(newPath);
1344
+ const oldBuf = iconv.encode(oldPath, this._encoding);
1345
+ const newBuf = iconv.encode(newPath, this._encoding);
1346
+ const oldLen = oldBuf.length;
1347
+ const newLen = newBuf.length;
1330
1348
  let p = 9;
1331
1349
  const buf =
1332
1350
  Buffer.allocUnsafe(4 + 1 + 4 + 4 + 24 + 4 + oldLen + 4 + newLen);
@@ -1339,9 +1357,9 @@ class SFTP extends EventEmitter {
1339
1357
  writeUInt32BE(buf, 24, p);
1340
1358
  buf.utf8Write('posix-rename@openssh.com', p += 4, 24);
1341
1359
  writeUInt32BE(buf, oldLen, p += 24);
1342
- buf.utf8Write(oldPath, p += 4, oldLen);
1360
+ buf.set(oldBuf, p += 4);
1343
1361
  writeUInt32BE(buf, newLen, p += oldLen);
1344
- buf.utf8Write(newPath, p += 4, newLen);
1362
+ buf.set(newBuf, p += 4);
1345
1363
 
1346
1364
  this._requests[reqid] = { cb };
1347
1365
 
@@ -1364,7 +1382,8 @@ class SFTP extends EventEmitter {
1364
1382
  string "statvfs@openssh.com"
1365
1383
  string path
1366
1384
  */
1367
- const pathLen = Buffer.byteLength(path);
1385
+ const pathBuf = iconv.encode(path, this._encoding);
1386
+ const pathLen = pathBuf.length;
1368
1387
  let p = 9;
1369
1388
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + 19 + 4 + pathLen);
1370
1389
 
@@ -1376,7 +1395,7 @@ class SFTP extends EventEmitter {
1376
1395
  writeUInt32BE(buf, 19, p);
1377
1396
  buf.utf8Write('statvfs@openssh.com', p += 4, 19);
1378
1397
  writeUInt32BE(buf, pathLen, p += 19);
1379
- buf.utf8Write(path, p += 4, pathLen);
1398
+ buf.set(pathBuf, p += 4);
1380
1399
 
1381
1400
  this._requests[reqid] = { extended: 'statvfs@openssh.com', cb };
1382
1401
 
@@ -1437,8 +1456,10 @@ class SFTP extends EventEmitter {
1437
1456
  string oldpath
1438
1457
  string newpath
1439
1458
  */
1440
- const oldLen = Buffer.byteLength(oldPath);
1441
- const newLen = Buffer.byteLength(newPath);
1459
+ const oldBuf = iconv.encode(oldPath, this._encoding);
1460
+ const newBuf = iconv.encode(newPath, this._encoding);
1461
+ const oldLen = oldBuf.length;
1462
+ const newLen = newBuf.length;
1442
1463
  let p = 9;
1443
1464
  const buf =
1444
1465
  Buffer.allocUnsafe(4 + 1 + 4 + 4 + 20 + 4 + oldLen + 4 + newLen);
@@ -1451,9 +1472,9 @@ class SFTP extends EventEmitter {
1451
1472
  writeUInt32BE(buf, 20, p);
1452
1473
  buf.utf8Write('hardlink@openssh.com', p += 4, 20);
1453
1474
  writeUInt32BE(buf, oldLen, p += 20);
1454
- buf.utf8Write(oldPath, p += 4, oldLen);
1475
+ buf.set(oldBuf, p += 4);
1455
1476
  writeUInt32BE(buf, newLen, p += oldLen);
1456
- buf.utf8Write(newPath, p += 4, newLen);
1477
+ buf.set(newBuf, p += 4);
1457
1478
 
1458
1479
  this._requests[reqid] = { cb };
1459
1480
 
@@ -1524,7 +1545,8 @@ class SFTP extends EventEmitter {
1524
1545
  string path
1525
1546
  ATTRS attrs
1526
1547
  */
1527
- const pathLen = Buffer.byteLength(path);
1548
+ const pathBuf = iconv.encode(path, this._encoding);
1549
+ const pathLen = pathBuf.length;
1528
1550
  let p = 9;
1529
1551
  const buf =
1530
1552
  Buffer.allocUnsafe(4 + 1 + 4 + 4 + 20 + 4 + pathLen + 4 + attrsLen);
@@ -1538,7 +1560,7 @@ class SFTP extends EventEmitter {
1538
1560
  buf.utf8Write('lsetstat@openssh.com', p += 4, 20);
1539
1561
 
1540
1562
  writeUInt32BE(buf, pathLen, p += 20);
1541
- buf.utf8Write(path, p += 4, pathLen);
1563
+ buf.set(pathBuf, p += 4);
1542
1564
 
1543
1565
  writeUInt32BE(buf, flags, p += pathLen);
1544
1566
  if (attrsLen) {
@@ -1573,7 +1595,8 @@ class SFTP extends EventEmitter {
1573
1595
  string "expand-path@openssh.com"
1574
1596
  string path
1575
1597
  */
1576
- const pathLen = Buffer.byteLength(path);
1598
+ const pathBuf = iconv.encode(path, this._encoding);
1599
+ const pathLen = pathBuf.length;
1577
1600
  let p = 9;
1578
1601
  const buf = Buffer.allocUnsafe(4 + 1 + 4 + 4 + 23 + 4 + pathLen);
1579
1602
 
@@ -1585,8 +1608,8 @@ class SFTP extends EventEmitter {
1585
1608
  writeUInt32BE(buf, 23, p);
1586
1609
  buf.utf8Write('expand-path@openssh.com', p += 4, 23);
1587
1610
 
1588
- writeUInt32BE(buf, pathLen, p += 20);
1589
- buf.utf8Write(path, p += 4, pathLen);
1611
+ writeUInt32BE(buf, pathLen, p += 23);
1612
+ buf.set(pathBuf, p += 4);
1590
1613
 
1591
1614
  this._requests[reqid] = {
1592
1615
  cb: (err, names) => {
@@ -2949,15 +2972,14 @@ const CLIENT_HANDLERS = {
2949
2972
  if (count !== undefined) {
2950
2973
  let names = [];
2951
2974
  for (let i = 0; i < count; ++i) {
2952
- // We are going to assume UTF-8 for filenames despite the SFTPv3
2953
- // spec not specifying an encoding because the specs for newer
2954
- // versions of the protocol all explicitly specify UTF-8 for
2955
- // filenames
2956
- const filename = bufferParser.readString(true);
2975
+ // Decode filenames using the configured encoding
2976
+ const filenameBuf = bufferParser.readString();
2977
+ const filename = (filenameBuf ? iconv.decode(filenameBuf, sftp._encoding) : '');
2957
2978
 
2958
2979
  // `longname` only exists in SFTPv3 and since it typically will
2959
- // contain the filename, we assume it is also UTF-8
2960
- const longname = bufferParser.readString(true);
2980
+ // contain the filename, we assume it uses the same encoding
2981
+ const longnameBuf = bufferParser.readString();
2982
+ const longname = (longnameBuf ? iconv.decode(longnameBuf, sftp._encoding) : '');
2961
2983
 
2962
2984
  const attrs = readAttrs(sftp._biOpt);
2963
2985
  if (attrs === undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/ssh2",
3
- "version": "1.17.2",
3
+ "version": "1.18.1",
4
4
  "author": "Brian White <mscdex@mscdex.net>",
5
5
  "description": "SSH2 client and server modules written in pure JavaScript for node.js",
6
6
  "main": "./lib/index.js",
@@ -9,7 +9,8 @@
9
9
  },
10
10
  "dependencies": {
11
11
  "asn1": "^0.2.6",
12
- "bcrypt-pbkdf": "^1.0.2"
12
+ "bcrypt-pbkdf": "^1.0.2",
13
+ "iconv-lite": "^0.7.2"
13
14
  },
14
15
  "devDependencies": {
15
16
  "@mscdex/eslint-config": "^1.1.0",