Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ssh2

Package Overview
Dependencies
Maintainers
1
Versions
105
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ssh2 - npm Package Compare versions

Comparing version 0.1.4 to 0.1.5

1

lib/Channel.js

@@ -662,2 +662,3 @@ var inherits = require('util').inherits,

this.outpaused = false;
this._decoder = undefined;
return ret;

@@ -664,0 +665,0 @@ };

7

lib/Connection.js

@@ -742,3 +742,6 @@ var net = require('net'),

if (self._sock.writable) {
var size = 1 + 4, buf, i, len = Math.min(nprompts, nanswers), p = 0;
var size = 1 + 4,
buf, i,
len = (nprompts < nanswers ? nprompts : nanswers),
p = 0;
for (i = 0; i < len; ++i) {

@@ -1009,3 +1012,3 @@ size += 4;

}
if (!this._privateKey.public) {
if (this._privateKey && !this._privateKey.public) {
// we get here if we didn't load a PuTTY key file

@@ -1012,0 +1015,0 @@ if (this._publicKey) {

@@ -47,2 +47,10 @@ var EventEmitter = require('events').EventEmitter,

SFTP.prototype.createReadStream = function(path, options) {
return new ReadStream(this, path, options);
};
SFTP.prototype.createWriteStream = function(path, options) {
return new WriteStream(this, path, options);
};
SFTP.prototype.open = function(filename, mode, attrs, cb) {

@@ -134,20 +142,9 @@

var isStreaming = false;
if (typeof length === 'function') {
isStreaming = true;
cb = length;
length = buffer;
position = offset;
buffer = undefined;
offset = undefined;
}
if (!Buffer.isBuffer(buffer))
throw new Error('buffer is not a Buffer');
else if (offset >= buffer.length)
throw new Error('offset is out of bounds');
else if (offset + length > buffer.length)
throw new Error('length extends beyond buffer');
if (!isStreaming) {
if (!Buffer.isBuffer(buffer))
throw new Error('buffer is not a Buffer');
else if (offset >= buffer.length)
throw new Error('offset is out of bounds');
else if (offset + length > buffer.length)
throw new Error('length extends beyond buffer');
}
if (position === null)

@@ -174,16 +171,7 @@ throw new Error('null position currently unsupported');

if (isStreaming) {
var stream = new ReadStream(this);
return this._send(buf, function(err) {
if (err)
return cb(err);
cb(undefined, stream);
}, stream);
} else {
return this._send(buf, function(err, bytesRead, data) {
if (err)
return cb(err);
cb(undefined, bytesRead, data);
}, undefined, buffer.slice(offset, offset + length));
}
return this._send(buf, function(err, bytesRead, data) {
if (err)
return cb(err);
cb(undefined, bytesRead || 0, data);
}, buffer.slice(offset, offset + length));
};

@@ -506,3 +494,3 @@

SFTP.prototype._send = function(data, cb, stream, buffer) {
SFTP.prototype._send = function(data, cb, buffer) {
var err;

@@ -543,10 +531,5 @@ if (this._reqid === MAX_REQID && !this._reqidmaxed) {

cb = EMPTY_CALLBACK;
else if (stream) {
// temporary callback hack used to ensure all is well before sending
// for streaming functions (currently read() and write())
cb();
cb = undefined;
}
this._requests[this._reqid] = { cb: cb, stream: stream, buffer: buffer };
this._requests[this._reqid] = { cb: cb, buffer: buffer };
/*

@@ -577,3 +560,3 @@ uint32 length

SFTP.prototype._parse = function(chunk) {
var data = this._data, chunklen = chunk.length, cb, stream;
var data = this._data, chunklen = chunk.length, cb;
chunk.i = 0;

@@ -628,12 +611,8 @@ while (chunk.i < chunklen) {

cb = this._requests[data.reqid].cb;
stream = this._requests[data.reqid].stream;
delete this._requests[data.reqid];
if (data.statusCode === STATUS_CODE.OK)
cb();
else if (data.statusCode === STATUS_CODE.EOF) {
if (stream)
stream.emit('end');
else
cb(undefined, false);
} else {
else if (data.statusCode === STATUS_CODE.EOF)
cb(undefined, false);
else {
var err = new Error(data.errMsg);

@@ -671,16 +650,8 @@ err.type = STATUS_CODE[data.statusCode];

} else if (data.subtype === 'data') {
if (this._requests[data.reqid].stream) {
if ((data.done = this._readString(chunk, undefined, true)) !== false) {
data.type = 'discard';
this._requests[data.reqid].stream.emit('end');
delete this._requests[data.reqid];
}
} else {
if ((data.data = this._readString(chunk)) !== false) {
data.type = 'discard';
cb = this._requests[data.reqid].cb;
var nbytes = this._requests[data.reqid].nbytes;
delete this._requests[data.reqid];
cb(undefined, nbytes, data.data);
}
if ((data.data = this._readString(chunk)) !== false) {
data.type = 'discard';
cb = this._requests[data.reqid].cb;
var nbytes = this._requests[data.reqid].nbytes;
delete this._requests[data.reqid];
cb(undefined, nbytes, data.data);
}

@@ -798,3 +769,3 @@ }

SFTP.prototype._readString = function(chunk, encoding, isDataStream) {
SFTP.prototype._readString = function(chunk, encoding) {
if (this._count < 4 && this._string === undefined) {

@@ -807,19 +778,17 @@ this._value <<= 8;

if (this._value === 0) {
if (isDataStream)
return true;
else if (!encoding)
if (!encoding) {
if (Buffer.isBuffer(this._requests[this._data.reqid].buffer))
this._requests[this._data.reqid].nbytes = 0;
return new Buffer(0);
else
} else
return '';
}
if (!isDataStream) {
if (!encoding) {
if (Buffer.isBuffer(this._requests[this._data.reqid].buffer)) {
this._string = this._requests[this._data.reqid].buffer;
this._requests[this._data.reqid].nbytes = this._value;
} else
this._string = new Buffer(this._value);
if (!encoding) {
if (Buffer.isBuffer(this._requests[this._data.reqid].buffer)) {
this._string = this._requests[this._data.reqid].buffer;
this._requests[this._data.reqid].nbytes = this._value;
} else
this._string = '';
}
this._string = new Buffer(this._value);
} else
this._string = '';
}

@@ -830,7 +799,3 @@ } else if (this._string !== undefined) {

var str;
if (isDataStream) {
this._requests[this._data.reqid]
.stream.emit('data', chunk.slice(chunk.i, chunk.i + this._value));
str = true;
} else if (!encoding) {
if (!encoding) {
chunk.copy(this._string, this._count, chunk.i, chunk.i + this._value);

@@ -852,6 +817,3 @@ str = this._string;

if (diff > 0) {
if (isDataStream) {
this._requests[this._data.reqid]
.stream.emit('data', chunk.slice(chunk.i));
} else if (!encoding) {
if (!encoding) {
chunk.copy(this._string, this._count, chunk.i);

@@ -1041,44 +1003,210 @@ this._count += diff;

function ReadStream(sftp) {
var kMinPoolSpace = 128,
kPoolSize = 40 * 1024,
pool;
function allocNewPool() {
pool = new Buffer(kPoolSize);
pool.used = 0;
}
function ReadStream(sftp, path, opts) {
var self = this;
this._sftp = sftp;
this._buffer = [];
this.path = path;
if (typeof this.path !== 'string')
throw new Error('path must be a string');
opts = opts || {};
this.readable = true;
this._paused = false;
this._decoder = undefined;
this.paused = false;
this.reading = false;
this.flags = opts.flags || 'r';
this.mode = opts.mode || 438; /*=0666*/
this.bufferSize = opts.bufferSize || (64 * 1024);
this.end = undefined;
this.pos = 0;
this.handle = undefined;
this.buffer = undefined;
if (opts.encoding)
this._decoder = this.setEncoding(opts.encoding);
else
this._decoder = undefined;
if (opts.start !== undefined) {
if (typeof opts.start !== 'number')
throw TypeError('start must be a Number');
if (opts.end === undefined)
this.end = Infinity;
else if (typeof opts.end !== 'number')
throw TypeError('end must be a Number');
else
this.end = opts.end;
if (opts.start > opts.end)
throw new Error('start must be <= end');
else if (opts.start < 0)
throw new Error('start must be >= zero');
this.pos = opts.start;
this.end = opts.end;
}
sftp.open(this.path, this.flags, this.mode, function(err, handle) {
if (err) {
self.emit('error', err);
self.readable = false;
return;
}
self.handle = handle;
self.emit('open', handle);
self._read();
});
sftp._stream._channel._conn._sock.once('end', function() {
self.readable = false;
});
sftp._stream._channel._conn._sock.once('close', function() {
self.readable = false;
});
}
inherits(ReadStream, Stream);
ReadStream.prototype._emit = ReadStream.prototype.emit;
ReadStream.prototype.emit = function(ev, arg1) {
if (this._paused)
this._buffer.push([ev, arg1]);
else {
if (ev === 'data' && this._decoder)
this._emit(ev, this._decoder.write(arg1));
else
this._emit(ev, arg1);
ReadStream.prototype._read = function() {
var self = this;
if (!this.readable || this.paused || this.reading) return;
this.reading = true;
if (!pool || pool.length - pool.used < kMinPoolSpace) {
// discard the old pool. Can't add to the free list because
// users might have references to slices on it.
pool = undefined;
allocNewPool();
}
// Grab another reference to the pool in the case that while we're in the
// thread pool another read() finishes up the pool, and allocates a new
// one.
var thisPool = pool,
toRead,
bufSize = ~~this.bufferSize,
diff = pool.length - pool.used,
start = pool.used;
if (diff < bufSize)
toRead = diff;
else
toRead = bufSize;
if (this.pos !== undefined && this.end !== undefined) {
diff = this.end - this.pos + 1;
if (diff < toRead)
toRead = diff;
}
function afterRead(err, bytesRead) {
self.reading = false;
if (err) {
self.emit('error', err);
self.readable = false;
return;
}
if (bytesRead === 0) {
self.emit('end');
self.destroy();
return;
}
var b = thisPool.slice(start, start + bytesRead);
// Possible optimizition here?
// Reclaim some bytes if bytesRead < toRead?
// Would need to ensure that pool === thisPool.
// do not emit events if the stream is paused
if (self.paused) {
self.buffer = b;
return;
}
// do not emit events anymore after we declared the stream unreadable
if (!self.readable)
return;
self._emitData(b);
self._read();
}
this._sftp.read(this.handle, pool, pool.used, toRead, this.pos, afterRead);
this.pos += toRead;
pool.used += toRead;
};
ReadStream.prototype._emitData = function(d) {
if (this._decoder) {
var string = this._decoder.write(d);
if (string.length)
this.emit('data', string);
} else
this.emit('data', d);
};
ReadStream.prototype.pause = function() {
this._sftp._stream.pause();
this._paused = true;
this.paused = true;
};
ReadStream.prototype.resume = function() {
if (this._buffer.length) {
for (var i = 0, len = this._buffer.length; i < len; ++i) {
if (this._buffer[i][0] === 'data' && this._decoder)
this._emit(this._buffer[i][0], this._decoder.write(this._buffer[i][1]));
else
this._emit(this._buffer[i][0], this._buffer[i][1]);
}
this._buffer = [];
this.paused = false;
if (this.buffer) {
var buffer = this.buffer;
this.buffer = undefined;
this._emitData(buffer);
}
this._paused = false;
this._sftp._stream.resume();
// hasn't opened yet.
if (this.handle === undefined)
return;
this._read();
};
ReadStream.prototype.destroy = function() {
var self = this;
this._decoder = undefined;
if (!this.readable) {
cb && process.nextTick(cb);
return;
}
this.readable = false;
this._buffer = [];
this._decoder = undefined;
function close() {
self._sftp.close(self.handle, function(err) {
if (err) {
cb && cb(err);
self.emit('error', err);
return;
}
cb && cb();
self.emit('close');
});
}
if (this.handle === undefined)
this.once('open', close);
else
close();
};
ReadStream.prototype.setEncoding = function(encoding) {

@@ -1088,1 +1216,169 @@ var StringDecoder = require('string_decoder').StringDecoder; // lazy load

};
function WriteStream(sftp, path, opts) {
var self = this;
this._sftp = sftp;
this.path = path;
if (typeof this.path !== 'string')
throw new TypeError('path must be a String');
opts = opts || {};
this.handle = undefined;
this.writable = true;
this.flags = opts.flags || 'w';
this.mode = opts.mode || 438; /*=0666*/
this.bytesWritten = 0;
this.pos = 0;
if (opts.start !== undefined) {
if (typeof opts.start !== 'number')
throw TypeError('start must be a Number');
if (opts.start < 0)
throw new Error('start must be >= zero');
this.pos = opts.start;
}
this.drainable = false;
this.busy = false;
this._queue = [[this._sftp.open, this.path, this.flags, this.mode, undefined]];
this.flush();
sftp._stream._channel._conn._sock.once('end', function() {
self.writable = false;
});
sftp._stream._channel._conn._sock.once('close', function() {
self.writable = false;
});
}
inherits(WriteStream, Stream);
WriteStream.prototype.flush = function() {
if (this.busy)
return;
var self = this;
var args = this._queue.shift();
if (!args) {
if (this.drainable)
this.emit('drain');
return;
}
this.busy = true;
var method = args.shift(),
cb = args.pop();
args.push(function(err, arg1) {
self.busy = false;
if (err) {
self.writable = false;
cb && cb(err);
self.emit('error', err);
return;
}
if (method === self._sftp.write) {
self.bytesWritten += arg1;
cb && cb(undefined, arg1);
} else if (method === self._sftp.open) {
// save reference for file handle
self.handle = arg1;
self.emit('open', self.handle);
} else if (method === self._sftp.close) {
// stop flushing after close
cb && cb();
self.emit('close');
return;
}
self.flush();
});
// Inject the file pointer
if (method !== this._sftp.open)
args.unshift(this.handle);
method.apply(this._sftp, args);
};
WriteStream.prototype.write = function(data, encoding, cb) {
if (!this.writable) {
this.emit('error', new Error('stream not writable'));
return false;
}
if (typeof encoding === 'function') {
cb = encoding;
encoding = undefined;
}
if (typeof cb !== 'function')
cb = undefined;
this.drainable = true;
if (!Buffer.isBuffer(data)) {
if (typeof encoding !== 'string')
encoding = 'utf8';
data = new Buffer('' + data, encoding);
}
this._queue.push([this._sftp.write, data, 0, data.length, this.pos, cb]);
this.pos += data.length;
this.flush();
return false;
};
WriteStream.prototype.end = function(data, encoding, cb) {
if (typeof data === 'function')
cb = data;
else if (typeof encoding === 'function') {
cb = encoding;
this.write(data);
} else if (data)
this.write(data, encoding);
this.writable = false;
this._queue.push([this._sftp.close, cb]);
this.flush();
};
WriteStream.prototype.destroy = function(cb) {
var self = this;
if (!this.writable) {
cb && process.nextTick(cb);
return;
}
this.writable = false;
function close() {
self._sftp.close(self.handle, function(err) {
if (err) {
cb && cb(err);
self.emit('error', err);
return;
}
cb && cb();
self.emit('close');
});
}
if (this.handle === null)
this.once('open', close);
else
close();
};
WriteStream.prototype.destroySoon = WriteStream.prototype.end;
{ "name": "ssh2",
"version": "0.1.4",
"version": "0.1.5",
"author": "Brian White <mscdex@mscdex.net>",

@@ -4,0 +4,0 @@ "description": "An SSH2 client module written in pure JavaScript for node.js",

@@ -446,2 +446,30 @@

* **createReadStream**(< _string_ >path[, < _object_ >options]) - _ReadStream_ - Returns a new readable stream for `path`. `options` has the following defaults:
```javascript
{ flags: 'r',
encoding: null,
mode: 0666,
bufferSize: 64 * 1024
}
```
`options` can include 'start' and 'end' values to read a range of bytes from the file instead of the entire file. Both 'start' and 'end' are inclusive and start at 0. The encoding can be 'utf8', 'ascii', or 'base64'.
An example to read the last 10 bytes of a file which is 100 bytes long:
```javascript
fs.createReadStream('sample.txt', {start: 90, end: 99});
```
* **createWriteStream**(< _string_ >path[, < _object_ >options]) - _WriteStream_ - Returns a new writable stream for `path`. `options` has the following defaults:
```javascript
{ flags: 'w',
encoding: null,
mode: 0666 }
```
`options` may also include a 'start' option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a flags mode of 'r+' rather than the default mode 'w'.
* **open**(< _string_ >filename, < _string_ >mode, [< _ATTRS_ >attributes, ]< _function_ >callback) - _(void)_ - Opens a file `filename` for `mode` with optional `attributes`. `mode` is any of the modes supported by fs.open (except sync mode). `callback` has 2 parameters: < _Error_ >err, < _Buffer_ >handle.

@@ -448,0 +476,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc