| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** @fileoverview Various string utility functions */ | 5 /** @fileoverview Various string utility functions */ |
| 6 'use strict'; | 6 'use strict'; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * Converts a string to an array of bytes. | 9 * Converts a string to an array of bytes. |
| 10 * @param {string} s The string to convert. | 10 * @param {string} s The string to convert. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 function UTIL_BytesToString(b) { | 27 function UTIL_BytesToString(b) { |
| 28 return String.fromCharCode.apply(null, b); | 28 return String.fromCharCode.apply(null, b); |
| 29 } | 29 } |
| 30 | 30 |
| 31 /** | 31 /** |
| 32 * Converts a byte array to a hex string. | 32 * Converts a byte array to a hex string. |
| 33 * @param {(Uint8Array|Array<number>)} b input byte array. | 33 * @param {(Uint8Array|Array<number>)} b input byte array. |
| 34 * @return {string} result. | 34 * @return {string} result. |
| 35 */ | 35 */ |
| 36 function UTIL_BytesToHex(b) { | 36 function UTIL_BytesToHex(b) { |
| 37 if (!b) return '(null)'; | 37 if (!b) |
| 38 return '(null)'; |
| 38 var hexchars = '0123456789ABCDEF'; | 39 var hexchars = '0123456789ABCDEF'; |
| 39 var hexrep = new Array(b.length * 2); | 40 var hexrep = new Array(b.length * 2); |
| 40 | 41 |
| 41 for (var i = 0; i < b.length; ++i) { | 42 for (var i = 0; i < b.length; ++i) { |
| 42 hexrep[i * 2 + 0] = hexchars.charAt((b[i] >> 4) & 15); | 43 hexrep[i * 2 + 0] = hexchars.charAt((b[i] >> 4) & 15); |
| 43 hexrep[i * 2 + 1] = hexchars.charAt(b[i] & 15); | 44 hexrep[i * 2 + 1] = hexchars.charAt(b[i] & 15); |
| 44 } | 45 } |
| 45 return hexrep.join(''); | 46 return hexrep.join(''); |
| 46 } | 47 } |
| 47 | 48 |
| 48 function UTIL_BytesToHexWithSeparator(b, sep) { | 49 function UTIL_BytesToHexWithSeparator(b, sep) { |
| 49 var hexchars = '0123456789ABCDEF'; | 50 var hexchars = '0123456789ABCDEF'; |
| 50 var stride = 2 + (sep ? 1 : 0); | 51 var stride = 2 + (sep ? 1 : 0); |
| 51 var hexrep = new Array(b.length * stride); | 52 var hexrep = new Array(b.length * stride); |
| 52 | 53 |
| 53 for (var i = 0; i < b.length; ++i) { | 54 for (var i = 0; i < b.length; ++i) { |
| 54 if (sep) hexrep[i * stride + 0] = sep; | 55 if (sep) |
| 56 hexrep[i * stride + 0] = sep; |
| 55 hexrep[i * stride + stride - 2] = hexchars.charAt((b[i] >> 4) & 15); | 57 hexrep[i * stride + stride - 2] = hexchars.charAt((b[i] >> 4) & 15); |
| 56 hexrep[i * stride + stride - 1] = hexchars.charAt(b[i] & 15); | 58 hexrep[i * stride + stride - 1] = hexchars.charAt(b[i] & 15); |
| 57 } | 59 } |
| 58 return (sep ? hexrep.slice(1) : hexrep).join(''); | 60 return (sep ? hexrep.slice(1) : hexrep).join(''); |
| 59 } | 61 } |
| 60 | 62 |
| 61 function UTIL_HexToBytes(h) { | 63 function UTIL_HexToBytes(h) { |
| 62 var hexchars = '0123456789ABCDEFabcdef'; | 64 var hexchars = '0123456789ABCDEFabcdef'; |
| 63 var res = new Uint8Array(h.length / 2); | 65 var res = new Uint8Array(h.length / 2); |
| 64 for (var i = 0; i < h.length; i += 2) { | 66 for (var i = 0; i < h.length; i += 2) { |
| 65 if (hexchars.indexOf(h.substring(i, i + 1)) == -1) break; | 67 if (hexchars.indexOf(h.substring(i, i + 1)) == -1) |
| 68 break; |
| 66 res[i / 2] = parseInt(h.substring(i, i + 2), 16); | 69 res[i / 2] = parseInt(h.substring(i, i + 2), 16); |
| 67 } | 70 } |
| 68 return res; | 71 return res; |
| 69 } | 72 } |
| 70 | 73 |
| 71 function UTIL_HexToArray(h) { | 74 function UTIL_HexToArray(h) { |
| 72 var hexchars = '0123456789ABCDEFabcdef'; | 75 var hexchars = '0123456789ABCDEFabcdef'; |
| 73 var res = new Array(h.length / 2); | 76 var res = new Array(h.length / 2); |
| 74 for (var i = 0; i < h.length; i += 2) { | 77 for (var i = 0; i < h.length; i += 2) { |
| 75 if (hexchars.indexOf(h.substring(i, i + 1)) == -1) break; | 78 if (hexchars.indexOf(h.substring(i, i + 1)) == -1) |
| 79 break; |
| 76 res[i / 2] = parseInt(h.substring(i, i + 2), 16); | 80 res[i / 2] = parseInt(h.substring(i, i + 2), 16); |
| 77 } | 81 } |
| 78 return res; | 82 return res; |
| 79 } | 83 } |
| 80 | 84 |
| 81 function UTIL_equalArrays(a, b) { | 85 function UTIL_equalArrays(a, b) { |
| 82 if (!a || !b) return false; | 86 if (!a || !b) |
| 83 if (a.length != b.length) return false; | 87 return false; |
| 88 if (a.length != b.length) |
| 89 return false; |
| 84 var accu = 0; | 90 var accu = 0; |
| 85 for (var i = 0; i < a.length; ++i) | 91 for (var i = 0; i < a.length; ++i) |
| 86 accu |= a[i] ^ b[i]; | 92 accu |= a[i] ^ b[i]; |
| 87 return accu === 0; | 93 return accu === 0; |
| 88 } | 94 } |
| 89 | 95 |
| 90 function UTIL_ltArrays(a, b) { | 96 function UTIL_ltArrays(a, b) { |
| 91 if (a.length < b.length) return true; | 97 if (a.length < b.length) |
| 92 if (a.length > b.length) return false; | 98 return true; |
| 99 if (a.length > b.length) |
| 100 return false; |
| 93 for (var i = 0; i < a.length; ++i) { | 101 for (var i = 0; i < a.length; ++i) { |
| 94 if (a[i] < b[i]) return true; | 102 if (a[i] < b[i]) |
| 95 if (a[i] > b[i]) return false; | 103 return true; |
| 104 if (a[i] > b[i]) |
| 105 return false; |
| 96 } | 106 } |
| 97 return false; | 107 return false; |
| 98 } | 108 } |
| 99 | 109 |
| 100 function UTIL_gtArrays(a, b) { | 110 function UTIL_gtArrays(a, b) { |
| 101 return UTIL_ltArrays(b, a); | 111 return UTIL_ltArrays(b, a); |
| 102 } | 112 } |
| 103 | 113 |
| 104 function UTIL_geArrays(a, b) { | 114 function UTIL_geArrays(a, b) { |
| 105 return !UTIL_ltArrays(a, b); | 115 return !UTIL_ltArrays(a, b); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 117 for (var k in obj) { | 127 for (var k in obj) { |
| 118 union.push(obj[k]); | 128 union.push(obj[k]); |
| 119 } | 129 } |
| 120 return union; | 130 return union; |
| 121 } | 131 } |
| 122 | 132 |
| 123 function UTIL_getRandom(a) { | 133 function UTIL_getRandom(a) { |
| 124 var tmp = new Array(a); | 134 var tmp = new Array(a); |
| 125 var rnd = new Uint8Array(a); | 135 var rnd = new Uint8Array(a); |
| 126 window.crypto.getRandomValues(rnd); // Yay! | 136 window.crypto.getRandomValues(rnd); // Yay! |
| 127 for (var i = 0; i < a; ++i) tmp[i] = rnd[i] & 255; | 137 for (var i = 0; i < a; ++i) |
| 138 tmp[i] = rnd[i] & 255; |
| 128 return tmp; | 139 return tmp; |
| 129 } | 140 } |
| 130 | 141 |
| 131 function UTIL_setFavicon(icon) { | 142 function UTIL_setFavicon(icon) { |
| 132 // Construct a new favion link tag | 143 // Construct a new favion link tag |
| 133 var faviconLink = document.createElement('link'); | 144 var faviconLink = document.createElement('link'); |
| 134 faviconLink.rel = 'Shortcut Icon'; | 145 faviconLink.rel = 'Shortcut Icon'; |
| 135 faviconLink.type = 'image/x-icon'; | 146 faviconLink.type = 'image/x-icon'; |
| 136 faviconLink.href = icon; | 147 faviconLink.href = icon; |
| 137 | 148 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 162 var UTIL_ASN_INT = 0x02; | 173 var UTIL_ASN_INT = 0x02; |
| 163 /** @const */ | 174 /** @const */ |
| 164 var UTIL_ASN_SEQUENCE = 0x30; | 175 var UTIL_ASN_SEQUENCE = 0x30; |
| 165 | 176 |
| 166 /** | 177 /** |
| 167 * Parse SEQ(INT, INT) from ASN1 byte array. | 178 * Parse SEQ(INT, INT) from ASN1 byte array. |
| 168 * @param {(Uint8Array|Array<number>)} a input to parse from. | 179 * @param {(Uint8Array|Array<number>)} a input to parse from. |
| 169 * @return {{'r': !Array<number>, 's': !Array<number>}|null} | 180 * @return {{'r': !Array<number>, 's': !Array<number>}|null} |
| 170 */ | 181 */ |
| 171 function UTIL_Asn1SignatureToJson(a) { | 182 function UTIL_Asn1SignatureToJson(a) { |
| 172 if (a.length < 6) return null; // Too small to be valid | 183 if (a.length < 6) |
| 173 if (a[0] != UTIL_ASN_SEQUENCE) return null; | 184 return null; // Too small to be valid |
| 185 if (a[0] != UTIL_ASN_SEQUENCE) |
| 186 return null; |
| 174 var l = a[1] & 255; | 187 var l = a[1] & 255; |
| 175 if (l & 0x80) return null; // SEQ.size too large | 188 if (l & 0x80) |
| 176 if (a.length != 2 + l) return null; // SEQ size does not match input | 189 return null; // SEQ.size too large |
| 190 if (a.length != 2 + l) |
| 191 return null; // SEQ size does not match input |
| 177 | 192 |
| 178 function parseInt(off) { | 193 function parseInt(off) { |
| 179 if (a[off] != UTIL_ASN_INT) return null; | 194 if (a[off] != UTIL_ASN_INT) |
| 195 return null; |
| 180 var l = a[off + 1] & 255; | 196 var l = a[off + 1] & 255; |
| 181 if (l & 0x80) return null; // INT.size too large | 197 if (l & 0x80) |
| 182 if (off + 2 + l > a.length) return null; // Out of bounds | 198 return null; // INT.size too large |
| 199 if (off + 2 + l > a.length) |
| 200 return null; // Out of bounds |
| 183 return a.slice(off + 2, off + 2 + l); | 201 return a.slice(off + 2, off + 2 + l); |
| 184 } | 202 } |
| 185 | 203 |
| 186 var r = parseInt(2); | 204 var r = parseInt(2); |
| 187 if (!r) return null; | 205 if (!r) |
| 206 return null; |
| 188 | 207 |
| 189 var s = parseInt(2 + 2 + r.length); | 208 var s = parseInt(2 + 2 + r.length); |
| 190 if (!s) return null; | 209 if (!s) |
| 210 return null; |
| 191 | 211 |
| 192 return {'r': r, 's': s}; | 212 return {'r': r, 's': s}; |
| 193 } | 213 } |
| 194 | 214 |
| 195 /** | 215 /** |
| 196 * Encode a JSON signature {r,s} as an ASN1 SEQ(INT, INT). May modify sig | 216 * Encode a JSON signature {r,s} as an ASN1 SEQ(INT, INT). May modify sig |
| 197 * @param {{'r': (!Array<number>|undefined), 's': !Array<number>}} sig | 217 * @param {{'r': (!Array<number>|undefined), 's': !Array<number>}} sig |
| 198 * @return {!Uint8Array} | 218 * @return {!Uint8Array} |
| 199 */ | 219 */ |
| 200 function UTIL_JsonSignatureToAsn1(sig) { | 220 function UTIL_JsonSignatureToAsn1(sig) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 221 i += rbytes.length; | 241 i += rbytes.length; |
| 222 | 242 |
| 223 buf[i++] = UTIL_ASN_INT; | 243 buf[i++] = UTIL_ASN_INT; |
| 224 buf[i++] = sbytes.length; | 244 buf[i++] = sbytes.length; |
| 225 buf.set(sbytes, i); | 245 buf.set(sbytes, i); |
| 226 | 246 |
| 227 return buf; | 247 return buf; |
| 228 } | 248 } |
| 229 | 249 |
| 230 function UTIL_prepend_zero(s, n) { | 250 function UTIL_prepend_zero(s, n) { |
| 231 if (s.length == n) return s; | 251 if (s.length == n) |
| 252 return s; |
| 232 var l = s.length; | 253 var l = s.length; |
| 233 for (var i = 0; i < n - l; ++i) { | 254 for (var i = 0; i < n - l; ++i) { |
| 234 s = '0' + s; | 255 s = '0' + s; |
| 235 } | 256 } |
| 236 return s; | 257 return s; |
| 237 } | 258 } |
| 238 | 259 |
| 239 // hr:min:sec.milli string | 260 // hr:min:sec.milli string |
| 240 function UTIL_time() { | 261 function UTIL_time() { |
| 241 var d = new Date(); | 262 var d = new Date(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 252 var UTIL_max_events = 500; | 273 var UTIL_max_events = 500; |
| 253 | 274 |
| 254 function UTIL_fmt(s) { | 275 function UTIL_fmt(s) { |
| 255 var line = UTIL_time() + ': ' + s; | 276 var line = UTIL_time() + ': ' + s; |
| 256 if (UTIL_events.push(line) > UTIL_max_events) { | 277 if (UTIL_events.push(line) > UTIL_max_events) { |
| 257 // Drop from head. | 278 // Drop from head. |
| 258 UTIL_events.splice(0, UTIL_events.length - UTIL_max_events); | 279 UTIL_events.splice(0, UTIL_events.length - UTIL_max_events); |
| 259 } | 280 } |
| 260 return line; | 281 return line; |
| 261 } | 282 } |
| OLD | NEW |