You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

406 lines
15 KiB

4 years ago
  1. /* eslint-disable node/no-deprecated-api */
  2. 'use strict'
  3. var test = require('tape')
  4. var buffer = require('buffer')
  5. var index = require('./')
  6. var safer = require('./safer')
  7. var dangerous = require('./dangerous')
  8. /* Inheritance tests */
  9. test('Default is Safer', function (t) {
  10. t.equal(index, safer)
  11. t.notEqual(safer, dangerous)
  12. t.notEqual(index, dangerous)
  13. t.end()
  14. })
  15. test('Is not a function', function (t) {
  16. [index, safer, dangerous].forEach(function (impl) {
  17. t.equal(typeof impl, 'object')
  18. t.equal(typeof impl.Buffer, 'object')
  19. });
  20. [buffer].forEach(function (impl) {
  21. t.equal(typeof impl, 'object')
  22. t.equal(typeof impl.Buffer, 'function')
  23. })
  24. t.end()
  25. })
  26. test('Constructor throws', function (t) {
  27. [index, safer, dangerous].forEach(function (impl) {
  28. t.throws(function () { impl.Buffer() })
  29. t.throws(function () { impl.Buffer(0) })
  30. t.throws(function () { impl.Buffer('a') })
  31. t.throws(function () { impl.Buffer('a', 'utf-8') })
  32. t.throws(function () { return new impl.Buffer() })
  33. t.throws(function () { return new impl.Buffer(0) })
  34. t.throws(function () { return new impl.Buffer('a') })
  35. t.throws(function () { return new impl.Buffer('a', 'utf-8') })
  36. })
  37. t.end()
  38. })
  39. test('Safe methods exist', function (t) {
  40. [index, safer, dangerous].forEach(function (impl) {
  41. t.equal(typeof impl.Buffer.alloc, 'function', 'alloc')
  42. t.equal(typeof impl.Buffer.from, 'function', 'from')
  43. })
  44. t.end()
  45. })
  46. test('Unsafe methods exist only in Dangerous', function (t) {
  47. [index, safer].forEach(function (impl) {
  48. t.equal(typeof impl.Buffer.allocUnsafe, 'undefined')
  49. t.equal(typeof impl.Buffer.allocUnsafeSlow, 'undefined')
  50. });
  51. [dangerous].forEach(function (impl) {
  52. t.equal(typeof impl.Buffer.allocUnsafe, 'function')
  53. t.equal(typeof impl.Buffer.allocUnsafeSlow, 'function')
  54. })
  55. t.end()
  56. })
  57. test('Generic methods/properties are defined and equal', function (t) {
  58. ['poolSize', 'isBuffer', 'concat', 'byteLength'].forEach(function (method) {
  59. [index, safer, dangerous].forEach(function (impl) {
  60. t.equal(impl.Buffer[method], buffer.Buffer[method], method)
  61. t.notEqual(typeof impl.Buffer[method], 'undefined', method)
  62. })
  63. })
  64. t.end()
  65. })
  66. test('Built-in buffer static methods/properties are inherited', function (t) {
  67. Object.keys(buffer).forEach(function (method) {
  68. if (method === 'SlowBuffer' || method === 'Buffer') return;
  69. [index, safer, dangerous].forEach(function (impl) {
  70. t.equal(impl[method], buffer[method], method)
  71. t.notEqual(typeof impl[method], 'undefined', method)
  72. })
  73. })
  74. t.end()
  75. })
  76. test('Built-in Buffer static methods/properties are inherited', function (t) {
  77. Object.keys(buffer.Buffer).forEach(function (method) {
  78. if (method === 'allocUnsafe' || method === 'allocUnsafeSlow') return;
  79. [index, safer, dangerous].forEach(function (impl) {
  80. t.equal(impl.Buffer[method], buffer.Buffer[method], method)
  81. t.notEqual(typeof impl.Buffer[method], 'undefined', method)
  82. })
  83. })
  84. t.end()
  85. })
  86. test('.prototype property of Buffer is inherited', function (t) {
  87. [index, safer, dangerous].forEach(function (impl) {
  88. t.equal(impl.Buffer.prototype, buffer.Buffer.prototype, 'prototype')
  89. t.notEqual(typeof impl.Buffer.prototype, 'undefined', 'prototype')
  90. })
  91. t.end()
  92. })
  93. test('All Safer methods are present in Dangerous', function (t) {
  94. Object.keys(safer).forEach(function (method) {
  95. if (method === 'Buffer') return;
  96. [index, safer, dangerous].forEach(function (impl) {
  97. t.equal(impl[method], safer[method], method)
  98. if (method !== 'kStringMaxLength') {
  99. t.notEqual(typeof impl[method], 'undefined', method)
  100. }
  101. })
  102. })
  103. Object.keys(safer.Buffer).forEach(function (method) {
  104. [index, safer, dangerous].forEach(function (impl) {
  105. t.equal(impl.Buffer[method], safer.Buffer[method], method)
  106. t.notEqual(typeof impl.Buffer[method], 'undefined', method)
  107. })
  108. })
  109. t.end()
  110. })
  111. test('Safe methods from Dangerous methods are present in Safer', function (t) {
  112. Object.keys(dangerous).forEach(function (method) {
  113. if (method === 'Buffer') return;
  114. [index, safer, dangerous].forEach(function (impl) {
  115. t.equal(impl[method], dangerous[method], method)
  116. if (method !== 'kStringMaxLength') {
  117. t.notEqual(typeof impl[method], 'undefined', method)
  118. }
  119. })
  120. })
  121. Object.keys(dangerous.Buffer).forEach(function (method) {
  122. if (method === 'allocUnsafe' || method === 'allocUnsafeSlow') return;
  123. [index, safer, dangerous].forEach(function (impl) {
  124. t.equal(impl.Buffer[method], dangerous.Buffer[method], method)
  125. t.notEqual(typeof impl.Buffer[method], 'undefined', method)
  126. })
  127. })
  128. t.end()
  129. })
  130. /* Behaviour tests */
  131. test('Methods return Buffers', function (t) {
  132. [index, safer, dangerous].forEach(function (impl) {
  133. t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(0)))
  134. t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(0, 10)))
  135. t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(0, 'a')))
  136. t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(10)))
  137. t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(10, 'x')))
  138. t.ok(buffer.Buffer.isBuffer(impl.Buffer.alloc(9, 'ab')))
  139. t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('')))
  140. t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('string')))
  141. t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('string', 'utf-8')))
  142. t.ok(buffer.Buffer.isBuffer(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64')))
  143. t.ok(buffer.Buffer.isBuffer(impl.Buffer.from([0, 42, 3])))
  144. t.ok(buffer.Buffer.isBuffer(impl.Buffer.from(new Uint8Array([0, 42, 3]))))
  145. t.ok(buffer.Buffer.isBuffer(impl.Buffer.from([])))
  146. });
  147. ['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) {
  148. t.ok(buffer.Buffer.isBuffer(dangerous.Buffer[method](0)))
  149. t.ok(buffer.Buffer.isBuffer(dangerous.Buffer[method](10)))
  150. })
  151. t.end()
  152. })
  153. test('Constructor is buffer.Buffer', function (t) {
  154. [index, safer, dangerous].forEach(function (impl) {
  155. t.equal(impl.Buffer.alloc(0).constructor, buffer.Buffer)
  156. t.equal(impl.Buffer.alloc(0, 10).constructor, buffer.Buffer)
  157. t.equal(impl.Buffer.alloc(0, 'a').constructor, buffer.Buffer)
  158. t.equal(impl.Buffer.alloc(10).constructor, buffer.Buffer)
  159. t.equal(impl.Buffer.alloc(10, 'x').constructor, buffer.Buffer)
  160. t.equal(impl.Buffer.alloc(9, 'ab').constructor, buffer.Buffer)
  161. t.equal(impl.Buffer.from('').constructor, buffer.Buffer)
  162. t.equal(impl.Buffer.from('string').constructor, buffer.Buffer)
  163. t.equal(impl.Buffer.from('string', 'utf-8').constructor, buffer.Buffer)
  164. t.equal(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64').constructor, buffer.Buffer)
  165. t.equal(impl.Buffer.from([0, 42, 3]).constructor, buffer.Buffer)
  166. t.equal(impl.Buffer.from(new Uint8Array([0, 42, 3])).constructor, buffer.Buffer)
  167. t.equal(impl.Buffer.from([]).constructor, buffer.Buffer)
  168. });
  169. [0, 10, 100].forEach(function (arg) {
  170. t.equal(dangerous.Buffer.allocUnsafe(arg).constructor, buffer.Buffer)
  171. t.equal(dangerous.Buffer.allocUnsafeSlow(arg).constructor, buffer.SlowBuffer(0).constructor)
  172. })
  173. t.end()
  174. })
  175. test('Invalid calls throw', function (t) {
  176. [index, safer, dangerous].forEach(function (impl) {
  177. t.throws(function () { impl.Buffer.from(0) })
  178. t.throws(function () { impl.Buffer.from(10) })
  179. t.throws(function () { impl.Buffer.from(10, 'utf-8') })
  180. t.throws(function () { impl.Buffer.from('string', 'invalid encoding') })
  181. t.throws(function () { impl.Buffer.from(-10) })
  182. t.throws(function () { impl.Buffer.from(1e90) })
  183. t.throws(function () { impl.Buffer.from(Infinity) })
  184. t.throws(function () { impl.Buffer.from(-Infinity) })
  185. t.throws(function () { impl.Buffer.from(NaN) })
  186. t.throws(function () { impl.Buffer.from(null) })
  187. t.throws(function () { impl.Buffer.from(undefined) })
  188. t.throws(function () { impl.Buffer.from() })
  189. t.throws(function () { impl.Buffer.from({}) })
  190. t.throws(function () { impl.Buffer.alloc('') })
  191. t.throws(function () { impl.Buffer.alloc('string') })
  192. t.throws(function () { impl.Buffer.alloc('string', 'utf-8') })
  193. t.throws(function () { impl.Buffer.alloc('b25ldHdvdGhyZWU=', 'base64') })
  194. t.throws(function () { impl.Buffer.alloc(-10) })
  195. t.throws(function () { impl.Buffer.alloc(1e90) })
  196. t.throws(function () { impl.Buffer.alloc(2 * (1 << 30)) })
  197. t.throws(function () { impl.Buffer.alloc(Infinity) })
  198. t.throws(function () { impl.Buffer.alloc(-Infinity) })
  199. t.throws(function () { impl.Buffer.alloc(null) })
  200. t.throws(function () { impl.Buffer.alloc(undefined) })
  201. t.throws(function () { impl.Buffer.alloc() })
  202. t.throws(function () { impl.Buffer.alloc([]) })
  203. t.throws(function () { impl.Buffer.alloc([0, 42, 3]) })
  204. t.throws(function () { impl.Buffer.alloc({}) })
  205. });
  206. ['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) {
  207. t.throws(function () { dangerous.Buffer[method]('') })
  208. t.throws(function () { dangerous.Buffer[method]('string') })
  209. t.throws(function () { dangerous.Buffer[method]('string', 'utf-8') })
  210. t.throws(function () { dangerous.Buffer[method](2 * (1 << 30)) })
  211. t.throws(function () { dangerous.Buffer[method](Infinity) })
  212. if (dangerous.Buffer[method] === buffer.Buffer.allocUnsafe) {
  213. t.skip('Skipping, older impl of allocUnsafe coerced negative sizes to 0')
  214. } else {
  215. t.throws(function () { dangerous.Buffer[method](-10) })
  216. t.throws(function () { dangerous.Buffer[method](-1e90) })
  217. t.throws(function () { dangerous.Buffer[method](-Infinity) })
  218. }
  219. t.throws(function () { dangerous.Buffer[method](null) })
  220. t.throws(function () { dangerous.Buffer[method](undefined) })
  221. t.throws(function () { dangerous.Buffer[method]() })
  222. t.throws(function () { dangerous.Buffer[method]([]) })
  223. t.throws(function () { dangerous.Buffer[method]([0, 42, 3]) })
  224. t.throws(function () { dangerous.Buffer[method]({}) })
  225. })
  226. t.end()
  227. })
  228. test('Buffers have appropriate lengths', function (t) {
  229. [index, safer, dangerous].forEach(function (impl) {
  230. t.equal(impl.Buffer.alloc(0).length, 0)
  231. t.equal(impl.Buffer.alloc(10).length, 10)
  232. t.equal(impl.Buffer.from('').length, 0)
  233. t.equal(impl.Buffer.from('string').length, 6)
  234. t.equal(impl.Buffer.from('string', 'utf-8').length, 6)
  235. t.equal(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64').length, 11)
  236. t.equal(impl.Buffer.from([0, 42, 3]).length, 3)
  237. t.equal(impl.Buffer.from(new Uint8Array([0, 42, 3])).length, 3)
  238. t.equal(impl.Buffer.from([]).length, 0)
  239. });
  240. ['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) {
  241. t.equal(dangerous.Buffer[method](0).length, 0)
  242. t.equal(dangerous.Buffer[method](10).length, 10)
  243. })
  244. t.end()
  245. })
  246. test('Buffers have appropriate lengths (2)', function (t) {
  247. t.equal(index.Buffer.alloc, safer.Buffer.alloc)
  248. t.equal(index.Buffer.alloc, dangerous.Buffer.alloc)
  249. var ok = true;
  250. [ safer.Buffer.alloc,
  251. dangerous.Buffer.allocUnsafe,
  252. dangerous.Buffer.allocUnsafeSlow
  253. ].forEach(function (method) {
  254. for (var i = 0; i < 1e2; i++) {
  255. var length = Math.round(Math.random() * 1e5)
  256. var buf = method(length)
  257. if (!buffer.Buffer.isBuffer(buf)) ok = false
  258. if (buf.length !== length) ok = false
  259. }
  260. })
  261. t.ok(ok)
  262. t.end()
  263. })
  264. test('.alloc(size) is zero-filled and has correct length', function (t) {
  265. t.equal(index.Buffer.alloc, safer.Buffer.alloc)
  266. t.equal(index.Buffer.alloc, dangerous.Buffer.alloc)
  267. var ok = true
  268. for (var i = 0; i < 1e2; i++) {
  269. var length = Math.round(Math.random() * 2e6)
  270. var buf = index.Buffer.alloc(length)
  271. if (!buffer.Buffer.isBuffer(buf)) ok = false
  272. if (buf.length !== length) ok = false
  273. var j
  274. for (j = 0; j < length; j++) {
  275. if (buf[j] !== 0) ok = false
  276. }
  277. buf.fill(1)
  278. for (j = 0; j < length; j++) {
  279. if (buf[j] !== 1) ok = false
  280. }
  281. }
  282. t.ok(ok)
  283. t.end()
  284. })
  285. test('.allocUnsafe / .allocUnsafeSlow are fillable and have correct lengths', function (t) {
  286. ['allocUnsafe', 'allocUnsafeSlow'].forEach(function (method) {
  287. var ok = true
  288. for (var i = 0; i < 1e2; i++) {
  289. var length = Math.round(Math.random() * 2e6)
  290. var buf = dangerous.Buffer[method](length)
  291. if (!buffer.Buffer.isBuffer(buf)) ok = false
  292. if (buf.length !== length) ok = false
  293. buf.fill(0, 0, length)
  294. var j
  295. for (j = 0; j < length; j++) {
  296. if (buf[j] !== 0) ok = false
  297. }
  298. buf.fill(1, 0, length)
  299. for (j = 0; j < length; j++) {
  300. if (buf[j] !== 1) ok = false
  301. }
  302. }
  303. t.ok(ok, method)
  304. })
  305. t.end()
  306. })
  307. test('.alloc(size, fill) is `fill`-filled', function (t) {
  308. t.equal(index.Buffer.alloc, safer.Buffer.alloc)
  309. t.equal(index.Buffer.alloc, dangerous.Buffer.alloc)
  310. var ok = true
  311. for (var i = 0; i < 1e2; i++) {
  312. var length = Math.round(Math.random() * 2e6)
  313. var fill = Math.round(Math.random() * 255)
  314. var buf = index.Buffer.alloc(length, fill)
  315. if (!buffer.Buffer.isBuffer(buf)) ok = false
  316. if (buf.length !== length) ok = false
  317. for (var j = 0; j < length; j++) {
  318. if (buf[j] !== fill) ok = false
  319. }
  320. }
  321. t.ok(ok)
  322. t.end()
  323. })
  324. test('.alloc(size, fill) is `fill`-filled', function (t) {
  325. t.equal(index.Buffer.alloc, safer.Buffer.alloc)
  326. t.equal(index.Buffer.alloc, dangerous.Buffer.alloc)
  327. var ok = true
  328. for (var i = 0; i < 1e2; i++) {
  329. var length = Math.round(Math.random() * 2e6)
  330. var fill = Math.round(Math.random() * 255)
  331. var buf = index.Buffer.alloc(length, fill)
  332. if (!buffer.Buffer.isBuffer(buf)) ok = false
  333. if (buf.length !== length) ok = false
  334. for (var j = 0; j < length; j++) {
  335. if (buf[j] !== fill) ok = false
  336. }
  337. }
  338. t.ok(ok)
  339. t.deepEqual(index.Buffer.alloc(9, 'a'), index.Buffer.alloc(9, 97))
  340. t.notDeepEqual(index.Buffer.alloc(9, 'a'), index.Buffer.alloc(9, 98))
  341. var tmp = new buffer.Buffer(2)
  342. tmp.fill('ok')
  343. if (tmp[1] === tmp[0]) {
  344. // Outdated Node.js
  345. t.deepEqual(index.Buffer.alloc(5, 'ok'), index.Buffer.from('ooooo'))
  346. } else {
  347. t.deepEqual(index.Buffer.alloc(5, 'ok'), index.Buffer.from('okoko'))
  348. }
  349. t.notDeepEqual(index.Buffer.alloc(5, 'ok'), index.Buffer.from('kokok'))
  350. t.end()
  351. })
  352. test('safer.Buffer.from returns results same as Buffer constructor', function (t) {
  353. [index, safer, dangerous].forEach(function (impl) {
  354. t.deepEqual(impl.Buffer.from(''), new buffer.Buffer(''))
  355. t.deepEqual(impl.Buffer.from('string'), new buffer.Buffer('string'))
  356. t.deepEqual(impl.Buffer.from('string', 'utf-8'), new buffer.Buffer('string', 'utf-8'))
  357. t.deepEqual(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64'), new buffer.Buffer('b25ldHdvdGhyZWU=', 'base64'))
  358. t.deepEqual(impl.Buffer.from([0, 42, 3]), new buffer.Buffer([0, 42, 3]))
  359. t.deepEqual(impl.Buffer.from(new Uint8Array([0, 42, 3])), new buffer.Buffer(new Uint8Array([0, 42, 3])))
  360. t.deepEqual(impl.Buffer.from([]), new buffer.Buffer([]))
  361. })
  362. t.end()
  363. })
  364. test('safer.Buffer.from returns consistent results', function (t) {
  365. [index, safer, dangerous].forEach(function (impl) {
  366. t.deepEqual(impl.Buffer.from(''), impl.Buffer.alloc(0))
  367. t.deepEqual(impl.Buffer.from([]), impl.Buffer.alloc(0))
  368. t.deepEqual(impl.Buffer.from(new Uint8Array([])), impl.Buffer.alloc(0))
  369. t.deepEqual(impl.Buffer.from('string', 'utf-8'), impl.Buffer.from('string'))
  370. t.deepEqual(impl.Buffer.from('string'), impl.Buffer.from([115, 116, 114, 105, 110, 103]))
  371. t.deepEqual(impl.Buffer.from('string'), impl.Buffer.from(impl.Buffer.from('string')))
  372. t.deepEqual(impl.Buffer.from('b25ldHdvdGhyZWU=', 'base64'), impl.Buffer.from('onetwothree'))
  373. t.notDeepEqual(impl.Buffer.from('b25ldHdvdGhyZWU='), impl.Buffer.from('onetwothree'))
  374. })
  375. t.end()
  376. })