|
106 | 106 | * @param {number=} seed_length Not supported.
|
107 | 107 | * @returns {string} Resulting salt
|
108 | 108 | * @throws {Error} If a random fallback is required but not set
|
109 |
| - * @expose |
110 | 109 | */
|
111 | 110 | bcrypt.genSaltSync = function(rounds, seed_length) {
|
112 | 111 | rounds = rounds || GENSALT_DEFAULT_LOG2_ROUNDS;
|
|
133 | 132 | * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting salt
|
134 | 133 | * @returns {!Promise} If `callback` has been omitted
|
135 | 134 | * @throws {Error} If `callback` is present but not a function
|
136 |
| - * @expose |
137 | 135 | */
|
138 | 136 | bcrypt.genSalt = function(rounds, seed_length, callback) {
|
139 | 137 | if (typeof seed_length === 'function')
|
|
178 | 176 | * @param {string} s String to hash
|
179 | 177 | * @param {(number|string)=} salt Salt length to generate or salt to use, default to 10
|
180 | 178 | * @returns {string} Resulting hash
|
181 |
| - * @expose |
182 | 179 | */
|
183 | 180 | bcrypt.hashSync = function(s, salt) {
|
184 | 181 | if (typeof salt === 'undefined')
|
|
199 | 196 | * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms.
|
200 | 197 | * @returns {!Promise} If `callback` has been omitted
|
201 | 198 | * @throws {Error} If `callback` is present but not a function
|
202 |
| - * @expose |
203 | 199 | */
|
204 | 200 | bcrypt.hash = function(s, salt, callback, progressCallback) {
|
205 | 201 |
|
|
238 | 234 | * @inner
|
239 | 235 | */
|
240 | 236 | function safeStringCompare(known, unknown) {
|
241 |
| - var right = 0, |
242 |
| - wrong = 0; |
243 |
| - for (var i=0, k=known.length; i<k; ++i) { |
244 |
| - if (known.charCodeAt(i) === unknown.charCodeAt(i)) |
245 |
| - ++right; |
246 |
| - else |
247 |
| - ++wrong; |
| 237 | + var diff = known.length ^ unknown.length; |
| 238 | + for (var i = 0; i < known.length; ++i) { |
| 239 | + diff |= known.charCodeAt(i) ^ unknown.charCodeAt(i); |
248 | 240 | }
|
249 |
| - // Prevent removal of unused variables (never true, actually) |
250 |
| - if (right < 0) |
251 |
| - return false; |
252 |
| - return wrong === 0; |
| 241 | + return diff === 0; |
253 | 242 | }
|
254 | 243 |
|
255 | 244 | /**
|
|
258 | 247 | * @param {string} hash Hash to test against
|
259 | 248 | * @returns {boolean} true if matching, otherwise false
|
260 | 249 | * @throws {Error} If an argument is illegal
|
261 |
| - * @expose |
262 | 250 | */
|
263 | 251 | bcrypt.compareSync = function(s, hash) {
|
264 | 252 | if (typeof s !== "string" || typeof hash !== "string")
|
|
277 | 265 | * (0.0 - 1.0), maximally once per `MAX_EXECUTION_TIME = 100` ms.
|
278 | 266 | * @returns {!Promise} If `callback` has been omitted
|
279 | 267 | * @throws {Error} If `callback` is present but not a function
|
280 |
| - * @expose |
281 | 268 | */
|
282 | 269 | bcrypt.compare = function(s, hash, callback, progressCallback) {
|
283 | 270 |
|
|
319 | 306 | * @param {string} hash Hash to extract the used number of rounds from
|
320 | 307 | * @returns {number} Number of rounds used
|
321 | 308 | * @throws {Error} If `hash` is not a string
|
322 |
| - * @expose |
323 | 309 | */
|
324 | 310 | bcrypt.getRounds = function(hash) {
|
325 | 311 | if (typeof hash !== "string")
|
|
332 | 318 | * @param {string} hash Hash to extract the salt from
|
333 | 319 | * @returns {string} Extracted salt part
|
334 | 320 | * @throws {Error} If `hash` is not a string or otherwise invalid
|
335 |
| - * @expose |
336 | 321 | */
|
337 | 322 | bcrypt.getSalt = function(hash) {
|
338 | 323 | if (typeof hash !== 'string')
|
|
352 | 337 | ? (typeof setImmediate === 'function' ? setImmediate : process.nextTick)
|
353 | 338 | : setTimeout;
|
354 | 339 |
|
| 340 | + /** Calculates the byte length of a string encoded as UTF8. */ |
| 341 | + function utf8Length(string) { |
| 342 | + var len = 0, |
| 343 | + c = 0; |
| 344 | + for (var i = 0; i < string.length; ++i) { |
| 345 | + c = string.charCodeAt(i); |
| 346 | + if (c < 128) |
| 347 | + len += 1; |
| 348 | + else if (c < 2048) |
| 349 | + len += 2; |
| 350 | + else if ( |
| 351 | + (c & 0xFC00) === 0xD800 && |
| 352 | + (string.charCodeAt(i + 1) & 0xFC00) === 0xDC00 |
| 353 | + ) { |
| 354 | + ++i; |
| 355 | + len += 4; |
| 356 | + } else |
| 357 | + len += 3; |
| 358 | + } |
| 359 | + return len; |
| 360 | + } |
| 361 | + |
| 362 | + /** Converts a string to an array of UTF8 bytes. */ |
| 363 | + function utf8Array(string) { |
| 364 | + var offset = 0, |
| 365 | + c1, c2; |
| 366 | + var buffer = new Array(utf8Length(string)); |
| 367 | + for (var i = 0, k = string.length; i < k; ++i) { |
| 368 | + c1 = string.charCodeAt(i); |
| 369 | + if (c1 < 128) { |
| 370 | + buffer[offset++] = c1; |
| 371 | + } else if (c1 < 2048) { |
| 372 | + buffer[offset++] = c1 >> 6 | 192; |
| 373 | + buffer[offset++] = c1 & 63 | 128; |
| 374 | + } else if ( |
| 375 | + ( c1 & 0xFC00) === 0xD800 && |
| 376 | + ((c2 = string.charCodeAt(i + 1)) & 0xFC00) === 0xDC00 |
| 377 | + ) { |
| 378 | + c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF); |
| 379 | + ++i; |
| 380 | + buffer[offset++] = c1 >> 18 | 240; |
| 381 | + buffer[offset++] = c1 >> 12 & 63 | 128; |
| 382 | + buffer[offset++] = c1 >> 6 & 63 | 128; |
| 383 | + buffer[offset++] = c1 & 63 | 128; |
| 384 | + } else { |
| 385 | + buffer[offset++] = c1 >> 12 | 224; |
| 386 | + buffer[offset++] = c1 >> 6 & 63 | 128; |
| 387 | + buffer[offset++] = c1 & 63 | 128; |
| 388 | + } |
| 389 | + } |
| 390 | + return buffer; |
| 391 | + } |
| 392 | + |
355 | 393 | /**
|
356 | 394 | * Converts a JavaScript string to UTF8 bytes.
|
| 395 | + * @function |
357 | 396 | * @param {string} str String
|
358 | 397 | * @returns {!Array.<number>} UTF8 bytes
|
359 | 398 | * @inner
|
360 | 399 | */
|
361 |
| - function stringToBytes(str) { |
362 |
| - var out = [], |
363 |
| - i = 0; |
364 |
| - utfx.encodeUTF16toUTF8(function() { |
365 |
| - if (i >= str.length) return null; |
366 |
| - return str.charCodeAt(i++); |
367 |
| - }, function(b) { |
368 |
| - out.push(b); |
369 |
| - }); |
370 |
| - return out; |
371 |
| - } |
| 400 | + var stringToBytes = utf8Array; |
372 | 401 |
|
373 | 402 | // A base64 implementation for the bcrypt algorithm. This is partly non-standard.
|
374 | 403 |
|
|
486 | 515 | return res;
|
487 | 516 | }
|
488 | 517 |
|
489 |
| - /** |
490 |
| - * utfx-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io> |
491 |
| - * Released under the Apache License, Version 2.0 |
492 |
| - * see: https://github.com/dcodeIO/utfx for details |
493 |
| - */ |
494 |
| - var utfx = function() { |
495 |
| - "use strict"; |
496 |
| - |
497 |
| - /** |
498 |
| - * utfx namespace. |
499 |
| - * @inner |
500 |
| - * @type {!Object.<string,*>} |
501 |
| - */ |
502 |
| - var utfx = {}; |
503 |
| - |
504 |
| - /** |
505 |
| - * Maximum valid code point. |
506 |
| - * @type {number} |
507 |
| - * @const |
508 |
| - */ |
509 |
| - utfx.MAX_CODEPOINT = 0x10FFFF; |
510 |
| - |
511 |
| - /** |
512 |
| - * Encodes UTF8 code points to UTF8 bytes. |
513 |
| - * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point |
514 |
| - * respectively `null` if there are no more code points left or a single numeric code point. |
515 |
| - * @param {!function(number)} dst Bytes destination as a function successively called with the next byte |
516 |
| - */ |
517 |
| - utfx.encodeUTF8 = function(src, dst) { |
518 |
| - var cp = null; |
519 |
| - if (typeof src === 'number') |
520 |
| - cp = src, |
521 |
| - src = function() { return null; }; |
522 |
| - while (cp !== null || (cp = src()) !== null) { |
523 |
| - if (cp < 0x80) |
524 |
| - dst(cp&0x7F); |
525 |
| - else if (cp < 0x800) |
526 |
| - dst(((cp>>6)&0x1F)|0xC0), |
527 |
| - dst((cp&0x3F)|0x80); |
528 |
| - else if (cp < 0x10000) |
529 |
| - dst(((cp>>12)&0x0F)|0xE0), |
530 |
| - dst(((cp>>6)&0x3F)|0x80), |
531 |
| - dst((cp&0x3F)|0x80); |
532 |
| - else |
533 |
| - dst(((cp>>18)&0x07)|0xF0), |
534 |
| - dst(((cp>>12)&0x3F)|0x80), |
535 |
| - dst(((cp>>6)&0x3F)|0x80), |
536 |
| - dst((cp&0x3F)|0x80); |
537 |
| - cp = null; |
538 |
| - } |
539 |
| - }; |
540 |
| - |
541 |
| - /** |
542 |
| - * Decodes UTF8 bytes to UTF8 code points. |
543 |
| - * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there |
544 |
| - * are no more bytes left. |
545 |
| - * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point. |
546 |
| - * @throws {RangeError} If a starting byte is invalid in UTF8 |
547 |
| - * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the |
548 |
| - * remaining bytes. |
549 |
| - */ |
550 |
| - utfx.decodeUTF8 = function(src, dst) { |
551 |
| - var a, b, c, d, fail = function(b) { |
552 |
| - b = b.slice(0, b.indexOf(null)); |
553 |
| - var err = Error(b.toString()); |
554 |
| - err.name = "TruncatedError"; |
555 |
| - err['bytes'] = b; |
556 |
| - throw err; |
557 |
| - }; |
558 |
| - while ((a = src()) !== null) { |
559 |
| - if ((a&0x80) === 0) |
560 |
| - dst(a); |
561 |
| - else if ((a&0xE0) === 0xC0) |
562 |
| - ((b = src()) === null) && fail([a, b]), |
563 |
| - dst(((a&0x1F)<<6) | (b&0x3F)); |
564 |
| - else if ((a&0xF0) === 0xE0) |
565 |
| - ((b=src()) === null || (c=src()) === null) && fail([a, b, c]), |
566 |
| - dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F)); |
567 |
| - else if ((a&0xF8) === 0xF0) |
568 |
| - ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]), |
569 |
| - dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F)); |
570 |
| - else throw RangeError("Illegal starting byte: "+a); |
571 |
| - } |
572 |
| - }; |
573 |
| - |
574 |
| - /** |
575 |
| - * Converts UTF16 characters to UTF8 code points. |
576 |
| - * @param {!function():number|null} src Characters source as a function returning the next char code respectively |
577 |
| - * `null` if there are no more characters left. |
578 |
| - * @param {!function(number)} dst Code points destination as a function successively called with each converted code |
579 |
| - * point. |
580 |
| - */ |
581 |
| - utfx.UTF16toUTF8 = function(src, dst) { |
582 |
| - var c1, c2 = null; |
583 |
| - while (true) { |
584 |
| - if ((c1 = c2 !== null ? c2 : src()) === null) |
585 |
| - break; |
586 |
| - if (c1 >= 0xD800 && c1 <= 0xDFFF) { |
587 |
| - if ((c2 = src()) !== null) { |
588 |
| - if (c2 >= 0xDC00 && c2 <= 0xDFFF) { |
589 |
| - dst((c1-0xD800)*0x400+c2-0xDC00+0x10000); |
590 |
| - c2 = null; continue; |
591 |
| - } |
592 |
| - } |
593 |
| - } |
594 |
| - dst(c1); |
595 |
| - } |
596 |
| - if (c2 !== null) dst(c2); |
597 |
| - }; |
598 |
| - |
599 |
| - /** |
600 |
| - * Converts UTF8 code points to UTF16 characters. |
601 |
| - * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point |
602 |
| - * respectively `null` if there are no more code points left or a single numeric code point. |
603 |
| - * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. |
604 |
| - * @throws {RangeError} If a code point is out of range |
605 |
| - */ |
606 |
| - utfx.UTF8toUTF16 = function(src, dst) { |
607 |
| - var cp = null; |
608 |
| - if (typeof src === 'number') |
609 |
| - cp = src, src = function() { return null; }; |
610 |
| - while (cp !== null || (cp = src()) !== null) { |
611 |
| - if (cp <= 0xFFFF) |
612 |
| - dst(cp); |
613 |
| - else |
614 |
| - cp -= 0x10000, |
615 |
| - dst((cp>>10)+0xD800), |
616 |
| - dst((cp%0x400)+0xDC00); |
617 |
| - cp = null; |
618 |
| - } |
619 |
| - }; |
620 |
| - |
621 |
| - /** |
622 |
| - * Converts and encodes UTF16 characters to UTF8 bytes. |
623 |
| - * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null` |
624 |
| - * if there are no more characters left. |
625 |
| - * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. |
626 |
| - */ |
627 |
| - utfx.encodeUTF16toUTF8 = function(src, dst) { |
628 |
| - utfx.UTF16toUTF8(src, function(cp) { |
629 |
| - utfx.encodeUTF8(cp, dst); |
630 |
| - }); |
631 |
| - }; |
632 |
| - |
633 |
| - /** |
634 |
| - * Decodes and converts UTF8 bytes to UTF16 characters. |
635 |
| - * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there |
636 |
| - * are no more bytes left. |
637 |
| - * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. |
638 |
| - * @throws {RangeError} If a starting byte is invalid in UTF8 |
639 |
| - * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes. |
640 |
| - */ |
641 |
| - utfx.decodeUTF8toUTF16 = function(src, dst) { |
642 |
| - utfx.decodeUTF8(src, function(cp) { |
643 |
| - utfx.UTF8toUTF16(cp, dst); |
644 |
| - }); |
645 |
| - }; |
646 |
| - |
647 |
| - /** |
648 |
| - * Calculates the byte length of an UTF8 code point. |
649 |
| - * @param {number} cp UTF8 code point |
650 |
| - * @returns {number} Byte length |
651 |
| - */ |
652 |
| - utfx.calculateCodePoint = function(cp) { |
653 |
| - return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; |
654 |
| - }; |
655 |
| - |
656 |
| - /** |
657 |
| - * Calculates the number of UTF8 bytes required to store UTF8 code points. |
658 |
| - * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively |
659 |
| - * `null` if there are no more code points left. |
660 |
| - * @returns {number} The number of UTF8 bytes required |
661 |
| - */ |
662 |
| - utfx.calculateUTF8 = function(src) { |
663 |
| - var cp, l=0; |
664 |
| - while ((cp = src()) !== null) |
665 |
| - l += utfx.calculateCodePoint(cp); |
666 |
| - return l; |
667 |
| - }; |
668 |
| - |
669 |
| - /** |
670 |
| - * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes. |
671 |
| - * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively |
672 |
| - * `null` if there are no more characters left. |
673 |
| - * @returns {!Array.<number>} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1. |
674 |
| - */ |
675 |
| - utfx.calculateUTF16asUTF8 = function(src) { |
676 |
| - var n=0, l=0; |
677 |
| - utfx.UTF16toUTF8(src, function(cp) { |
678 |
| - ++n; l += utfx.calculateCodePoint(cp); |
679 |
| - }); |
680 |
| - return [n,l]; |
681 |
| - }; |
682 |
| - |
683 |
| - return utfx; |
684 |
| - }(); |
685 |
| - |
686 | 518 | Date.now = Date.now || function() { return +new Date; };
|
687 | 519 |
|
688 | 520 | /**
|
|
1361 | 1193 | * @param {!Array.<number>} b Byte array
|
1362 | 1194 | * @param {number} len Maximum input length
|
1363 | 1195 | * @returns {string}
|
1364 |
| - * @expose |
1365 | 1196 | */
|
1366 | 1197 | bcrypt.encodeBase64 = base64_encode;
|
1367 | 1198 |
|
|
1371 | 1202 | * @param {string} s String to decode
|
1372 | 1203 | * @param {number} len Maximum output length
|
1373 | 1204 | * @returns {!Array.<number>}
|
1374 |
| - * @expose |
1375 | 1205 | */
|
1376 | 1206 | bcrypt.decodeBase64 = base64_decode;
|
1377 | 1207 |
|
|
0 commit comments