/**
 * @author Michael Raith
 * @date   24.02.2016 12:04
 */

'use strict';

var crypto = require('crypto');
var bufferAlloc = require('buffer-alloc');


/**
 * Do a constant time string comparison. Always compare the complete strings
 * against each other to get a constant time. This method does not short-cut
 * if the two string's length differs.
 *
 * @param {string} a
 * @param {string} b
 * 
 * @return {boolean}
 */
var safeCompare = function safeCompare(a, b) {
    var strA = String(a);
    var strB = String(b);
    var lenA = strA.length;
    var result = 0;

    if (lenA !== strB.length) {
        strB = strA;
        result = 1;
    }

    for (var i = 0; i < lenA; i++) {
        result |= (strA.charCodeAt(i) ^ strB.charCodeAt(i));
    }

    return result === 0;
};


/**
 * Call native "crypto.timingSafeEqual" methods.
 * All passed values will be converted into strings first.
 * 
 * @param {string} a
 * @param {string} b
 * 
 * @return {boolean}
 */
var nativeTimingSafeEqual = function nativeTimingSafeEqual(a, b) {
    var strA = String(a);
    var strB = String(b);
    
    var len = Math.max(Buffer.byteLength(strA), Buffer.byteLength(strB));
    
    var bufA = bufferAlloc(len, 0, 'utf8');
    bufA.write(strA);
    var bufB = bufferAlloc(len, 0, 'utf8');
    bufB.write(strB);
    
    return crypto.timingSafeEqual(bufA, bufB);
};


module.exports = (
    typeof crypto.timingSafeEqual !== 'undefined' ?
        nativeTimingSafeEqual :
        safeCompare
);

@@ -383,33 +383,32 @@
 am %7Bstring%7D b%0A *
- 
 %0A * @return %7Bboo
@@ -894,17 +894,106 @@
 irst.%0A *
- 
+%0A * Runtime is always corresponding to the length of the first parameter (string%0A * a).%0A *
 %0A * @par
@@ -1029,17 +1029,16 @@
 ng%7D b%0A *
- 
 %0A * @ret
@@ -1174,29 +1174,24 @@
 ing(b);%0A
-    %0A
     var 
 len = Ma
@@ -1186,23 +1186,15 @@
 var 
-l
+aL
 en = 
-Math.max(
 Buff
@@ -1212,17 +1212,32 @@
 th(strA)
-,
+;%0A    var bLen =
  Buffer.
@@ -1252,23 +1252,216 @@
 th(strB)
-)
 ;
+%0A
 %0A    
+// Always use length of a to avoid leaking the length. Even if this is a%0A    // false positive because one is a prefix of the other, the explicit length%0A    // check at the end will catch that.
 %0A    var
@@ -1472,33 +1472,34 @@
 A = bufferAlloc(
-l
+aL
 en, 0, 'utf8');%0A
@@ -1547,17 +1547,18 @@
 erAlloc(
-l
+aL
 en, 0, '
@@ -1587,20 +1587,16 @@
 (strB);%0A
-    
 %0A    ret
@@ -1633,16 +1633,33 @@
 A, bufB)
+ && aLen === bLen
 ;%0A%7D;%0A%0A%0Am

Fix leaking length of comparator string