ssh-buffer.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2015 Joyent, Inc.
  2. module.exports = SSHBuffer;
  3. var assert = require('assert-plus');
  4. function SSHBuffer(opts) {
  5. assert.object(opts, 'options');
  6. if (opts.buffer !== undefined)
  7. assert.buffer(opts.buffer, 'options.buffer');
  8. this._size = opts.buffer ? opts.buffer.length : 1024;
  9. this._buffer = opts.buffer || (new Buffer(this._size));
  10. this._offset = 0;
  11. }
  12. SSHBuffer.prototype.toBuffer = function () {
  13. return (this._buffer.slice(0, this._offset));
  14. };
  15. SSHBuffer.prototype.atEnd = function () {
  16. return (this._offset >= this._buffer.length);
  17. };
  18. SSHBuffer.prototype.remainder = function () {
  19. return (this._buffer.slice(this._offset));
  20. };
  21. SSHBuffer.prototype.skip = function (n) {
  22. this._offset += n;
  23. };
  24. SSHBuffer.prototype.expand = function () {
  25. this._size *= 2;
  26. var buf = new Buffer(this._size);
  27. this._buffer.copy(buf, 0);
  28. this._buffer = buf;
  29. };
  30. SSHBuffer.prototype.readPart = function () {
  31. return ({data: this.readBuffer()});
  32. };
  33. SSHBuffer.prototype.readBuffer = function () {
  34. var len = this._buffer.readUInt32BE(this._offset);
  35. this._offset += 4;
  36. assert.ok(this._offset + len <= this._buffer.length,
  37. 'length out of bounds at +0x' + this._offset.toString(16) +
  38. ' (data truncated?)');
  39. var buf = this._buffer.slice(this._offset, this._offset + len);
  40. this._offset += len;
  41. return (buf);
  42. };
  43. SSHBuffer.prototype.readString = function () {
  44. return (this.readBuffer().toString());
  45. };
  46. SSHBuffer.prototype.readCString = function () {
  47. var offset = this._offset;
  48. while (offset < this._buffer.length &&
  49. this._buffer[offset] !== 0x00)
  50. offset++;
  51. assert.ok(offset < this._buffer.length, 'c string does not terminate');
  52. var str = this._buffer.slice(this._offset, offset).toString();
  53. this._offset = offset + 1;
  54. return (str);
  55. };
  56. SSHBuffer.prototype.readInt = function () {
  57. var v = this._buffer.readUInt32BE(this._offset);
  58. this._offset += 4;
  59. return (v);
  60. };
  61. SSHBuffer.prototype.readInt64 = function () {
  62. assert.ok(this._offset + 8 < this._buffer.length,
  63. 'buffer not long enough to read Int64');
  64. var v = this._buffer.slice(this._offset, this._offset + 8);
  65. this._offset += 8;
  66. return (v);
  67. };
  68. SSHBuffer.prototype.readChar = function () {
  69. var v = this._buffer[this._offset++];
  70. return (v);
  71. };
  72. SSHBuffer.prototype.writeBuffer = function (buf) {
  73. while (this._offset + 4 + buf.length > this._size)
  74. this.expand();
  75. this._buffer.writeUInt32BE(buf.length, this._offset);
  76. this._offset += 4;
  77. buf.copy(this._buffer, this._offset);
  78. this._offset += buf.length;
  79. };
  80. SSHBuffer.prototype.writeString = function (str) {
  81. this.writeBuffer(new Buffer(str, 'utf8'));
  82. };
  83. SSHBuffer.prototype.writeCString = function (str) {
  84. while (this._offset + 1 + str.length > this._size)
  85. this.expand();
  86. this._buffer.write(str, this._offset);
  87. this._offset += str.length;
  88. this._buffer[this._offset++] = 0;
  89. };
  90. SSHBuffer.prototype.writeInt = function (v) {
  91. while (this._offset + 4 > this._size)
  92. this.expand();
  93. this._buffer.writeUInt32BE(v, this._offset);
  94. this._offset += 4;
  95. };
  96. SSHBuffer.prototype.writeInt64 = function (v) {
  97. assert.buffer(v, 'value');
  98. if (v.length > 8) {
  99. var lead = v.slice(0, v.length - 8);
  100. for (var i = 0; i < lead.length; ++i) {
  101. assert.strictEqual(lead[i], 0,
  102. 'must fit in 64 bits of precision');
  103. }
  104. v = v.slice(v.length - 8, v.length);
  105. }
  106. while (this._offset + 8 > this._size)
  107. this.expand();
  108. v.copy(this._buffer, this._offset);
  109. this._offset += 8;
  110. };
  111. SSHBuffer.prototype.writeChar = function (v) {
  112. while (this._offset + 1 > this._size)
  113. this.expand();
  114. this._buffer[this._offset++] = v;
  115. };
  116. SSHBuffer.prototype.writePart = function (p) {
  117. this.writeBuffer(p.data);
  118. };
  119. SSHBuffer.prototype.write = function (buf) {
  120. while (this._offset + buf.length > this._size)
  121. this.expand();
  122. buf.copy(this._buffer, this._offset);
  123. this._offset += buf.length;
  124. };