| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c065773 commit a0e2c6d
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,7 +12,7 @@ const { | |||
| 12 | 12 | ERR_INVALID_ARG_TYPE, | |
| 13 | 13 | ERR_INVALID_OPT_VALUE | |
| 14 | 14 | } = require('internal/errors').codes; | |
| 15 | - const { validateString } = require('internal/validators'); | ||
| 15 | + const { validateEncoding, validateString } = require('internal/validators'); | ||
| 16 | 16 | ||
| 17 | 17 | const { | |
| 18 | 18 | preparePrivateKey, | |
@@ -161,6 +161,8 @@ Cipher.prototype.update = function update(data, inputEncoding, outputEncoding) { | |||
| 161 | 161 | throw invalidArrayBufferView('data', data); | |
| 162 | 162 | } | |
| 163 | 163 | ||
| 164 | + validateEncoding(data, inputEncoding); | ||
| 165 | + | ||
| 164 | 166 | const ret = this[kHandle].update(data, inputEncoding); | |
| 165 | 167 | ||
| 166 | 168 | if (outputEncoding && outputEncoding !== 'buffer') { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -25,7 +25,8 @@ const { | |||
| 25 | 25 | ERR_CRYPTO_HASH_UPDATE_FAILED, | |
| 26 | 26 | ERR_INVALID_ARG_TYPE | |
| 27 | 27 | } = require('internal/errors').codes; | |
| 28 | - const { validateString, validateUint32 } = require('internal/validators'); | ||
| 28 | + const { validateEncoding, validateString, validateUint32 } = | ||
| 29 | + require('internal/validators'); | ||
| 29 | 30 | const { normalizeEncoding } = require('internal/util'); | |
| 30 | 31 | const { isArrayBufferView } = require('internal/util/types'); | |
| 31 | 32 | const LazyTransform = require('internal/streams/lazy_transform'); | |
@@ -61,6 +62,8 @@ Hash.prototype._flush = function _flush(callback) { | |||
| 61 | 62 | }; | |
| 62 | 63 | ||
| 63 | 64 | Hash.prototype.update = function update(data, encoding) { | |
| 65 | + encoding = encoding || getDefaultEncoding(); | ||
| 66 | + | ||
| 64 | 67 | const state = this[kState]; | |
| 65 | 68 | if (state[kFinalized]) | |
| 66 | 69 | throw new ERR_CRYPTO_HASH_FINALIZED(); | |
@@ -74,7 +77,9 @@ Hash.prototype.update = function update(data, encoding) { | |||
| 74 | 77 | data); | |
| 75 | 78 | } | |
| 76 | 79 | ||
| 77 | - if (!this[kHandle].update(data, encoding || getDefaultEncoding())) | ||
| 80 | + validateEncoding(data, encoding); | ||
| 81 | + | ||
| 82 | + if (!this[kHandle].update(data, encoding)) | ||
| 78 | 83 | throw new ERR_CRYPTO_HASH_UPDATE_FAILED(); | |
| 79 | 84 | return this; | |
| 80 | 85 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,6 +9,7 @@ const { | |||
| 9 | 9 | ERR_UNKNOWN_SIGNAL | |
| 10 | 10 | } | |
| 11 | 11 | } = require('internal/errors'); | |
| 12 | + const { normalizeEncoding } = require('internal/util'); | ||
| 12 | 13 | const { | |
| 13 | 14 | isArrayBufferView | |
| 14 | 15 | } = require('internal/util/types'); | |
@@ -142,11 +143,24 @@ const validateBuffer = hideStackFrames((buffer, name = 'buffer') => { | |||
| 142 | 143 | } | |
| 143 | 144 | }); | |
| 144 | 145 | ||
| 146 | + function validateEncoding(data, encoding) { | ||
| 147 | + const normalizedEncoding = normalizeEncoding(encoding); | ||
| 148 | + const length = data.length; | ||
| 149 | + | ||
| 150 | + if (normalizedEncoding === 'hex' && length % 2 !== 0) { | ||
| 151 | + throw new ERR_INVALID_ARG_VALUE('encoding', encoding, | ||
| 152 | + `is invalid for data of length ${length}`); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + // TODO(bnoordhuis) Add BASE64 check? | ||
| 156 | + } | ||
| 157 | + | ||
| 145 | 158 | module.exports = { | |
| 146 | 159 | isInt32, | |
| 147 | 160 | isUint32, | |
| 148 | 161 | parseMode, | |
| 149 | 162 | validateBuffer, | |
| 163 | + validateEncoding, | ||
| 150 | 164 | validateInteger, | |
| 151 | 165 | validateInt32, | |
| 152 | 166 | validateUint32, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -843,7 +843,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) { | |||
| 843 | 843 | ||
| 844 | 844 | if (IsBigEndian()) { | |
| 845 | 845 | StringBytes::InlineDecoder decoder; | |
| 846 | - if (decoder.Decode(env, needle, args[3], UCS2).IsNothing()) return; | ||
| 846 | + if (decoder.Decode(env, needle, enc).IsNothing()) return; | ||
| 847 | 847 | const uint16_t* decoded_string = | |
| 848 | 848 | reinterpret_cast<const uint16_t*>(decoder.out()); | |
| 849 | 849 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4317,8 +4317,9 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) { | |||
| 4317 | 4317 | // Only copy the data if we have to, because it's a string | |
| 4318 | 4318 | if (args[0]->IsString()) { | |
| 4319 | 4319 | StringBytes::InlineDecoder decoder; | |
| 4320 | - if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8) | ||
| 4321 | - .FromMaybe(false)) | ||
| 4320 | + enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8); | ||
| 4321 | + | ||
| 4322 | + if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing()) | ||
| 4322 | 4323 | return; | |
| 4323 | 4324 | r = cipher->Update(decoder.out(), decoder.size(), &out); | |
| 4324 | 4325 | } else { | |
@@ -4501,8 +4502,9 @@ void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) { | |||
| 4501 | 4502 | bool r = false; | |
| 4502 | 4503 | if (args[0]->IsString()) { | |
| 4503 | 4504 | StringBytes::InlineDecoder decoder; | |
| 4504 | - if (decoder.Decode(env, args[0].As<String>(), args[1], UTF8) | ||
| 4505 | - .FromMaybe(false)) { | ||
| 4505 | + enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8); | ||
| 4506 | + | ||
| 4507 | + if (!decoder.Decode(env, args[0].As<String>(), enc).IsNothing()) { | ||
| 4506 | 4508 | r = hmac->HmacUpdate(decoder.out(), decoder.size()); | |
| 4507 | 4509 | } | |
| 4508 | 4510 | } else { | |
@@ -4626,8 +4628,9 @@ void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) { | |||
| 4626 | 4628 | bool r = true; | |
| 4627 | 4629 | if (args[0]->IsString()) { | |
| 4628 | 4630 | StringBytes::InlineDecoder decoder; | |
| 4629 | - if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8) | ||
| 4630 | - .FromMaybe(false)) { | ||
| 4631 | + enum encoding enc = ParseEncoding(env->isolate(), args[1], UTF8); | ||
| 4632 | + | ||
| 4633 | + if (decoder.Decode(env, args[0].As<String>(), enc).IsNothing()) { | ||
| 4631 | 4634 | args.GetReturnValue().Set(false); | |
| 4632 | 4635 | return; | |
| 4633 | 4636 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -392,15 +392,6 @@ size_t StringBytes::Write(Isolate* isolate, | |||
| 392 | 392 | } | |
| 393 | 393 | ||
| 394 | 394 | ||
| 395 | - bool StringBytes::IsValidString(Local<String> string, | ||
| 396 | - enum encoding enc) { | ||
| 397 | - if (enc == HEX && string->Length() % 2 != 0) | ||
| 398 | - return false; | ||
| 399 | - // TODO(bnoordhuis) Add BASE64 check? | ||
| 400 | - return true; | ||
| 401 | - } | ||
| 402 | - | ||
| 403 | - | ||
| 404 | 395 | // Quick and dirty size calculation | |
| 405 | 396 | // Will always be at least big enough, but may have some extra | |
| 406 | 397 | // UTF8 can be as much as 3x the size, Base64 can have 1-2 extra bytes | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -37,14 +37,7 @@ class StringBytes { | |||
| 37 | 37 | public: | |
| 38 | 38 | inline v8::Maybe<bool> Decode(Environment* env, | |
| 39 | 39 | v8::Local<v8::String> string, | |
| 40 | - v8::Local<v8::Value> encoding, | ||
| 41 | - enum encoding _default) { | ||
| 42 | - enum encoding enc = ParseEncoding(env->isolate(), encoding, _default); | ||
| 43 | - if (!StringBytes::IsValidString(string, enc)) { | ||
| 44 | - env->ThrowTypeError("Bad input string"); | ||
| 45 | - return v8::Nothing<bool>(); | ||
| 46 | - } | ||
| 47 | - | ||
| 40 | + enum encoding enc) { | ||
| 48 | 41 | size_t storage; | |
| 49 | 42 | if (!StringBytes::StorageSize(env->isolate(), string, enc).To(&storage)) | |
| 50 | 43 | return v8::Nothing<bool>(); | |
@@ -60,12 +53,6 @@ class StringBytes { | |||
| 60 | 53 | inline size_t size() const { return length(); } | |
| 61 | 54 | }; | |
| 62 | 55 | ||
| 63 | - // Does the string match the encoding? Quick but non-exhaustive. | ||
| 64 | - // Example: a HEX string must have a length that's a multiple of two. | ||
| 65 | - // FIXME(bnoordhuis) IsMaybeValidString()? Naming things is hard... | ||
| 66 | - static bool IsValidString(v8::Local<v8::String> string, | ||
| 67 | - enum encoding enc); | ||
| 68 | - | ||
| 69 | 56 | // Fast, but can be 2 bytes oversized for Base64, and | |
| 70 | 57 | // as much as triple UTF-8 strings <= 65536 chars in length | |
| 71 | 58 | static v8::Maybe<size_t> StorageSize(v8::Isolate* isolate, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -167,42 +167,66 @@ testImmutability(crypto.getCurves); | |||
| 167 | 167 | ||
| 168 | 168 | // Regression tests for https://github.com/nodejs/node-v0.x-archive/pull/5725: | |
| 169 | 169 | // hex input that's not a power of two should throw, not assert in C++ land. | |
| 170 | - assert.throws(function() { | ||
| 171 | - crypto.createCipher('aes192', 'test').update('0', 'hex'); | ||
| 172 | - }, (err) => { | ||
| 173 | - const errorMessage = | ||
| 174 | - common.hasFipsCrypto ? /not supported in FIPS mode/ : /Bad input string/; | ||
| 175 | - // Throws general Error, so there is no opensslErrorStack property. | ||
| 176 | - if ((err instanceof Error) && | ||
| 177 | - errorMessage.test(err) && | ||
| 178 | - err.opensslErrorStack === undefined) { | ||
| 179 | - return true; | ||
| 180 | - } | ||
| 181 | - }); | ||
| 182 | 170 | ||
| 183 | - assert.throws(function() { | ||
| 184 | - crypto.createDecipher('aes192', 'test').update('0', 'hex'); | ||
| 185 | - }, (err) => { | ||
| 186 | - const errorMessage = | ||
| 187 | - common.hasFipsCrypto ? /not supported in FIPS mode/ : /Bad input string/; | ||
| 188 | - // Throws general Error, so there is no opensslErrorStack property. | ||
| 189 | - if ((err instanceof Error) && | ||
| 190 | - errorMessage.test(err) && | ||
| 191 | - err.opensslErrorStack === undefined) { | ||
| 192 | - return true; | ||
| 171 | + common.expectsError( | ||
| 172 | + () => crypto.createCipher('aes192', 'test').update('0', 'hex'), | ||
| 173 | + Object.assign( | ||
| 174 | + common.hasFipsCrypto ? | ||
| 175 | + { | ||
| 176 | + code: undefined, | ||
| 177 | + type: Error, | ||
| 178 | + message: /not supported in FIPS mode/, | ||
| 179 | + } : | ||
| 180 | + { | ||
| 181 | + code: 'ERR_INVALID_ARG_VALUE', | ||
| 182 | + type: TypeError, | ||
| 183 | + message: "The argument 'encoding' is invalid for data of length 1." + | ||
| 184 | + " Received 'hex'", | ||
| 185 | + }, | ||
| 186 | + { opensslErrorStack: undefined } | ||
| 187 | + ) | ||
| 188 | + ); | ||
| 189 | + | ||
| 190 | + common.expectsError( | ||
| 191 | + () => crypto.createDecipher('aes192', 'test').update('0', 'hex'), | ||
| 192 | + Object.assign( | ||
| 193 | + common.hasFipsCrypto ? | ||
| 194 | + { | ||
| 195 | + code: undefined, | ||
| 196 | + type: Error, | ||
| 197 | + message: /not supported in FIPS mode/, | ||
| 198 | + } : | ||
| 199 | + { | ||
| 200 | + code: 'ERR_INVALID_ARG_VALUE', | ||
| 201 | + type: TypeError, | ||
| 202 | + message: "The argument 'encoding' is invalid for data of length 1." + | ||
| 203 | + " Received 'hex'", | ||
| 204 | + }, | ||
| 205 | + { opensslErrorStack: undefined } | ||
| 206 | + ) | ||
| 207 | + ); | ||
| 208 | + | ||
| 209 | + common.expectsError( | ||
| 210 | + () => crypto.createHash('sha1').update('0', 'hex'), | ||
| 211 | + { | ||
| 212 | + code: 'ERR_INVALID_ARG_VALUE', | ||
| 213 | + type: TypeError, | ||
| 214 | + message: "The argument 'encoding' is invalid for data of length 1." + | ||
| 215 | + " Received 'hex'", | ||
| 216 | + opensslErrorStack: undefined | ||
| 193 | 217 | } | |
| 194 | - }); | ||
| 218 | + ); | ||
| 195 | 219 | ||
| 196 | - assert.throws(function() { | ||
| 197 | - crypto.createHash('sha1').update('0', 'hex'); | ||
| 198 | - }, (err) => { | ||
| 199 | - // Throws TypeError, so there is no opensslErrorStack property. | ||
| 200 | - if ((err instanceof Error) && | ||
| 201 | - /^TypeError: Bad input string$/.test(err) && | ||
| 202 | - err.opensslErrorStack === undefined) { | ||
| 203 | - return true; | ||
| 220 | + common.expectsError( | ||
| 221 | + () => crypto.createHmac('sha256', 'a secret').update('0', 'hex'), | ||
| 222 | + { | ||
| 223 | + code: 'ERR_INVALID_ARG_VALUE', | ||
| 224 | + type: TypeError, | ||
| 225 | + message: "The argument 'encoding' is invalid for data of length 1." + | ||
| 226 | + " Received 'hex'", | ||
| 227 | + opensslErrorStack: undefined | ||
| 204 | 228 | } | |
| 205 | - }); | ||
| 229 | + ); | ||
| 206 | 230 | ||
| 207 | 231 | assert.throws(function() { | |
| 208 | 232 | const priv = [ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments