2525
2626#include " node.h"
2727#include " node_buffer.h"
28+ #include " string_bytes.h"
2829#include " node_root_certs.h"
2930
3031#include < string.h>
4142# define OPENSSL_CONST
4243#endif
4344
45+ #define ASSERT_IS_STRING_OR_BUFFER (val ) \
46+ if (!Buffer::HasInstance(val) && !val->IsString ()) { \
47+ return ThrowException (Exception::TypeError (String::New ( \
48+ " Not a string or buffer" ))); \
49+ }
50+
4451#define ASSERT_IS_BUFFER (val ) \
4552 if (!Buffer::HasInstance(val)) { \
4653 return ThrowException (Exception::TypeError (String::New (" Not a buffer" ))); \
@@ -2225,24 +2232,33 @@ class Cipher : public ObjectWrap {
22252232
22262233 HandleScope scope;
22272234
2228- ASSERT_IS_BUFFER (args[0 ]);
2235+ ASSERT_IS_STRING_OR_BUFFER (args[0 ]);
22292236
2237+ // Only copy the data if we have to, because it's a string
22302238 unsigned char * out=0 ;
22312239 int out_len=0 , r;
2232- char * buffer_data = Buffer::Data (args[0 ]);
2233- size_t buffer_length = Buffer::Length (args[0 ]);
2234-
2235- r = cipher->CipherUpdate (buffer_data, buffer_length, &out, &out_len);
2240+ if (args[0 ]->IsString ()) {
2241+ enum encoding encoding = ParseEncoding (args[1 ], BINARY);
2242+ size_t buflen = StringBytes::SizeFast (args[0 ], encoding);
2243+ char * buf = static_cast <char *>(malloc (buflen));
2244+ size_t written = StringBytes::Write (buf, buflen, args[0 ], encoding);
2245+ r = cipher->CipherUpdate (buf, written, &out, &out_len);
2246+ free (buf);
2247+ } else {
2248+ char * buf = Buffer::Data (args[0 ]);
2249+ size_t buflen = Buffer::Length (args[0 ]);
2250+ r = cipher->CipherUpdate (buf, buflen, &out, &out_len);
2251+ }
22362252
22372253 if (r == 0 ) {
2238- delete [] out;
2254+ delete[] out;
22392255 return ThrowCryptoTypeError (ERR_get_error ());
22402256 }
22412257
22422258 Local<Value> outString;
22432259 outString = Encode (out, out_len, BUFFER);
22442260
2245- if (out) delete [] out;
2261+ if (out) delete[] out;
22462262
22472263 return scope.Close (outString);
22482264 }
@@ -2525,25 +2541,26 @@ class Decipher : public ObjectWrap {
25252541
25262542 Decipher *cipher = ObjectWrap::Unwrap<Decipher>(args.This ());
25272543
2528- ASSERT_IS_BUFFER (args[0 ]);
2529-
2530- ssize_t len;
2531-
2532- char * buf;
2533- // if alloc_buf then buf must be deleted later
2534- bool alloc_buf = false ;
2535- char * buffer_data = Buffer::Data (args[0 ]);
2536- size_t buffer_length = Buffer::Length (args[0 ]);
2537-
2538- buf = buffer_data;
2539- len = buffer_length;
2544+ ASSERT_IS_STRING_OR_BUFFER (args[0 ]);
25402545
2546+ // Only copy the data if we have to, because it's a string
25412547 unsigned char * out=0 ;
2542- int out_len=0 ;
2543- int r = cipher->DecipherUpdate (buf, len, &out, &out_len);
2548+ int out_len=0 , r;
2549+ if (args[0 ]->IsString ()) {
2550+ enum encoding encoding = ParseEncoding (args[1 ], BINARY);
2551+ size_t buflen = StringBytes::SizeFast (args[0 ], encoding);
2552+ char * buf = static_cast <char *>(malloc (buflen));
2553+ size_t written = StringBytes::Write (buf, buflen, args[0 ], encoding);
2554+ r = cipher->DecipherUpdate (buf, written, &out, &out_len);
2555+ free (buf);
2556+ } else {
2557+ char * buf = Buffer::Data (args[0 ]);
2558+ size_t buflen = Buffer::Length (args[0 ]);
2559+ r = cipher->DecipherUpdate (buf, buflen, &out, &out_len);
2560+ }
25442561
2545- if (!r ) {
2546- delete [] out;
2562+ if (r == 0 ) {
2563+ delete[] out;
25472564 return ThrowCryptoTypeError (ERR_get_error ());
25482565 }
25492566
@@ -2552,9 +2569,7 @@ class Decipher : public ObjectWrap {
25522569
25532570 if (out) delete [] out;
25542571
2555- if (alloc_buf) delete [] buf;
25562572 return scope.Close (outString);
2557-
25582573 }
25592574
25602575 static Handle<Value> SetAutoPadding (const Arguments& args) {
@@ -2716,14 +2731,22 @@ class Hmac : public ObjectWrap {
27162731
27172732 HandleScope scope;
27182733
2719- ASSERT_IS_BUFFER (args[0 ]);
2734+ ASSERT_IS_STRING_OR_BUFFER (args[0 ]);
27202735
2736+ // Only copy the data if we have to, because it's a string
27212737 int r;
2722-
2723- char * buffer_data = Buffer::Data (args[0 ]);
2724- size_t buffer_length = Buffer::Length (args[0 ]);
2725-
2726- r = hmac->HmacUpdate (buffer_data, buffer_length);
2738+ if (args[0 ]->IsString ()) {
2739+ enum encoding encoding = ParseEncoding (args[1 ], BINARY);
2740+ size_t buflen = StringBytes::SizeFast (args[0 ], encoding);
2741+ char * buf = static_cast <char *>(malloc (buflen));
2742+ size_t written = StringBytes::Write (buf, buflen, args[0 ], encoding);
2743+ r = hmac->HmacUpdate (buf, written);
2744+ free (buf);
2745+ } else {
2746+ char * buf = Buffer::Data (args[0 ]);
2747+ size_t buflen = Buffer::Length (args[0 ]);
2748+ r = hmac->HmacUpdate (buf, buflen);
2749+ }
27272750
27282751 if (!r) {
27292752 Local<Value> exception = Exception::TypeError (String::New (" HmacUpdate fail" ));
@@ -2831,13 +2854,22 @@ class Hash : public ObjectWrap {
28312854
28322855 Hash *hash = ObjectWrap::Unwrap<Hash>(args.This ());
28332856
2834- ASSERT_IS_BUFFER (args[0 ]);
2857+ ASSERT_IS_STRING_OR_BUFFER (args[0 ]);
28352858
2859+ // Only copy the data if we have to, because it's a string
28362860 int r;
2837-
2838- char * buffer_data = Buffer::Data (args[0 ]);
2839- size_t buffer_length = Buffer::Length (args[0 ]);
2840- r = hash->HashUpdate (buffer_data, buffer_length);
2861+ if (args[0 ]->IsString ()) {
2862+ enum encoding encoding = ParseEncoding (args[1 ], BINARY);
2863+ size_t buflen = StringBytes::SizeFast (args[0 ], encoding);
2864+ char * buf = static_cast <char *>(malloc (buflen));
2865+ size_t written = StringBytes::Write (buf, buflen, args[0 ], encoding);
2866+ r = hash->HashUpdate (buf, written);
2867+ free (buf);
2868+ } else {
2869+ char * buf = Buffer::Data (args[0 ]);
2870+ size_t buflen = Buffer::Length (args[0 ]);
2871+ r = hash->HashUpdate (buf, buflen);
2872+ }
28412873
28422874 if (!r) {
28432875 Local<Value> exception = Exception::TypeError (String::New (" HashUpdate fail" ));
@@ -2983,14 +3015,22 @@ class Sign : public ObjectWrap {
29833015
29843016 HandleScope scope;
29853017
2986- ASSERT_IS_BUFFER (args[0 ]);
3018+ ASSERT_IS_STRING_OR_BUFFER (args[0 ]);
29873019
3020+ // Only copy the data if we have to, because it's a string
29883021 int r;
2989-
2990- char * buffer_data = Buffer::Data (args[0 ]);
2991- size_t buffer_length = Buffer::Length (args[0 ]);
2992-
2993- r = sign->SignUpdate (buffer_data, buffer_length);
3022+ if (args[0 ]->IsString ()) {
3023+ enum encoding encoding = ParseEncoding (args[1 ], BINARY);
3024+ size_t buflen = StringBytes::SizeFast (args[0 ], encoding);
3025+ char * buf = static_cast <char *>(malloc (buflen));
3026+ size_t written = StringBytes::Write (buf, buflen, args[0 ], encoding);
3027+ r = sign->SignUpdate (buf, written);
3028+ free (buf);
3029+ } else {
3030+ char * buf = Buffer::Data (args[0 ]);
3031+ size_t buflen = Buffer::Length (args[0 ]);
3032+ r = sign->SignUpdate (buf, buflen);
3033+ }
29943034
29953035 if (!r) {
29963036 Local<Value> exception = Exception::TypeError (String::New (" SignUpdate fail" ));
@@ -3194,14 +3234,22 @@ class Verify : public ObjectWrap {
31943234
31953235 Verify *verify = ObjectWrap::Unwrap<Verify>(args.This ());
31963236
3197- ASSERT_IS_BUFFER (args[0 ]);
3237+ ASSERT_IS_STRING_OR_BUFFER (args[0 ]);
31983238
3239+ // Only copy the data if we have to, because it's a string
31993240 int r;
3200-
3201- char * buffer_data = Buffer::Data (args[0 ]);
3202- size_t buffer_length = Buffer::Length (args[0 ]);
3203-
3204- r = verify->VerifyUpdate (buffer_data, buffer_length);
3241+ if (args[0 ]->IsString ()) {
3242+ enum encoding encoding = ParseEncoding (args[1 ], BINARY);
3243+ size_t buflen = StringBytes::SizeFast (args[0 ], encoding);
3244+ char * buf = static_cast <char *>(malloc (buflen));
3245+ size_t written = StringBytes::Write (buf, buflen, args[0 ], encoding);
3246+ r = verify->VerifyUpdate (buf, written);
3247+ free (buf);
3248+ } else {
3249+ char * buf = Buffer::Data (args[0 ]);
3250+ size_t buflen = Buffer::Length (args[0 ]);
3251+ r = verify->VerifyUpdate (buf, buflen);
3252+ }
32053253
32063254 if (!r) {
32073255 Local<Value> exception = Exception::TypeError (String::New (" VerifyUpdate fail" ));
0 commit comments