diff options
author | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2014-06-01 11:29:00 +0100 |
---|---|---|
committer | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2014-06-01 11:29:00 +0100 |
commit | 207902b174bce23e6a15fc8e1c84389928c3db35 (patch) | |
tree | e249ccee2566e8f2b7283149bd13f699cbb46c0b /cpan/Digest-SHA/SHA.xs | |
parent | d5e64588cb11db6bd730a216490fb0402b21eb07 (diff) | |
download | perl-207902b174bce23e6a15fc8e1c84389928c3db35.tar.gz |
Update Digest-SHA to CPAN version 5.92
[DELTA]
5.92 Sun Jun 1 00:15:44 MST 2014
- fixed reserved-word clash when compiling with C++
-- use 'classname' instead of 'class'
-- ref. SHA.xs (rt.cpan.org #96090)
- silenced MSC compiler warning about signed/unsigned comparison
-- ref. SHA.xs (rt.cpan.org #95830)
5.91 Fri May 16 10:21:44 MST 2014
- restored original 'addfile' for use on opened file handles
-- allows callbacks in place of actual files
-- ref. IO::Callback (rt.cpan.org #95643)
- re-established inheritance from Digest::base
-- to pick up future Digest enhancements automatically
- cleaned up documentation
5.90 Wed May 7 07:57:08 MST 2014
- consolidated all dynamic memory allocation into XSUBs
-- streamlines referencing of SHA objects
-- simplifies DESTROYing of objects
- enhanced Makefile.PL to allow 'use warnings'
-- automatically reverts to $^W for early Perls
- scrubbed C and Perl code to remove all compiler warnings
5.89 Sat Apr 19 05:14:48 MST 2014
- added universal newlines mode ("U") to addfile and shasum
-- based on Python Universal Newlines concept
-- newlines identical across MacOS, DOS, and UNIX
-- will deprecate portable mode ("p") in future
-- "U" mode is cleaner and more efficient
- enhanced performance
-- reduced number of dynamic memory allocations
-- sped up addfile method with use of C code
-- ref. SHA.xs (_addfilebin and _addfileuniv)
- eliminated experimental -M option in favor of new -R option
-- reverses order of digest module preference
-- undocumented: for test and development use only
- sealed memory leak in SHA.xs
-- arose only with SvPVbyte exceptions during eval
- patched inheritence bug (ref: rt.cpan.org #94830)
-- use sv_isobject/sv_derived_from instead of sv_isa
- added 'allocated' flag to SHA structure (ref. src/sha.h)
-- to guard against Perl double frees
Diffstat (limited to 'cpan/Digest-SHA/SHA.xs')
-rw-r--r-- | cpan/Digest-SHA/SHA.xs | 270 |
1 files changed, 190 insertions, 80 deletions
diff --git a/cpan/Digest-SHA/SHA.xs b/cpan/Digest-SHA/SHA.xs index c38fcc4d9d..c7a7f34610 100644 --- a/cpan/Digest-SHA/SHA.xs +++ b/cpan/Digest-SHA/SHA.xs @@ -12,37 +12,47 @@ #define SvPVbyte SvPV #endif +#ifndef PerlIO + #define PerlIO FILE + #define PerlIO_read(f, buf, count) fread(buf, 1, count, f) +#endif + +#ifndef sv_derived_from + #include "src/sdf.c" +#endif + +#ifndef Newx + #define Newx(ptr, num, type) New(0, ptr, num, type) + #define Newxz(ptr, num, type) Newz(0, ptr, num, type) +#endif + #include "src/sha.c" static int ix2alg[] = {1,1,1,224,224,224,256,256,256,384,384,384,512,512,512, 512224,512224,512224,512256,512256,512256}; -MODULE = Digest::SHA PACKAGE = Digest::SHA - -PROTOTYPES: ENABLE - #ifndef INT2PTR #define INT2PTR(p, i) (p) (i) #endif #define MAX_WRITE_SIZE 16384 +#define IO_BUFFER_SIZE 4096 -int -shaclose(s) - SHA * s -CODE: - RETVAL = shaclose(s); - sv_setiv(SvRV(ST(0)), 0); -OUTPUT: - RETVAL +static SHA *getSHA(SV *self) +{ + if (!sv_isobject(self) || !sv_derived_from(self, "Digest::SHA")) + return(NULL); + return INT2PTR(SHA *, SvIV(SvRV(self))); +} -SHA * -shadup(s) - SHA * s +MODULE = Digest::SHA PACKAGE = Digest::SHA + +PROTOTYPES: ENABLE -SHA * -shaopen(alg) +int +shainit(s, alg) + SHA * s int alg void @@ -55,7 +65,48 @@ shawrite(bitstr, bitcnt, s) unsigned long bitcnt SHA * s +SV * +newSHA(classname, alg) + char * classname + int alg +PREINIT: + SHA *state; +CODE: + Newxz(state, 1, SHA); + if (!shainit(state, alg)) { + Safefree(state); + XSRETURN_UNDEF; + } + RETVAL = newSV(0); + sv_setref_pv(RETVAL, classname, (void *) state); + SvREADONLY_on(SvRV(RETVAL)); +OUTPUT: + RETVAL + +SV * +clone(self) + SV * self +PREINIT: + SHA *state; + SHA *clone; +CODE: + if ((state = getSHA(self)) == NULL) + XSRETURN_UNDEF; + Newx(clone, 1, SHA); + RETVAL = newSV(0); + sv_setref_pv(RETVAL, sv_reftype(SvRV(self), 1), (void *) clone); + SvREADONLY_on(SvRV(RETVAL)); + Copy(state, clone, 1, SHA); +OUTPUT: + RETVAL + void +DESTROY(s) + SHA * s +CODE: + Safefree(s); + +SV * sha1(...) ALIAS: Digest::SHA::sha1 = 0 @@ -83,35 +134,35 @@ PREINIT: int i; UCHR *data; STRLEN len; - SHA *state; + SHA sha; char *result; -PPCODE: - if ((state = shaopen(ix2alg[ix])) == NULL) +CODE: + if (!shainit(&sha, ix2alg[ix])) XSRETURN_UNDEF; for (i = 0; i < items; i++) { data = (UCHR *) (SvPVbyte(ST(i), len)); while (len > MAX_WRITE_SIZE) { - shawrite(data, MAX_WRITE_SIZE << 3, state); + shawrite(data, MAX_WRITE_SIZE << 3, &sha); data += MAX_WRITE_SIZE; len -= MAX_WRITE_SIZE; } - shawrite(data, len << 3, state); + shawrite(data, len << 3, &sha); } - shafinish(state); + shafinish(&sha); len = 0; if (ix % 3 == 0) { - result = (char *) digcpy(state); - len = state->digestlen; + result = (char *) shadigest(&sha); + len = sha.digestlen; } else if (ix % 3 == 1) - result = shahex(state); + result = shahex(&sha); else - result = shabase64(state); - ST(0) = sv_2mortal(newSVpv(result, len)); - shaclose(state); - XSRETURN(1); + result = shabase64(&sha); + RETVAL = newSVpv(result, len); +OUTPUT: + RETVAL -void +SV * hmac_sha1(...) ALIAS: Digest::SHA::hmac_sha1 = 0 @@ -137,39 +188,41 @@ ALIAS: Digest::SHA::hmac_sha512256_base64 = 20 PREINIT: int i; - UCHR *key; + UCHR *key = (UCHR *) ""; UCHR *data; - STRLEN len; - HMAC *state; + STRLEN len = 0; + HMAC hmac; char *result; -PPCODE: - key = (UCHR *) (SvPVbyte(ST(items-1), len)); - if ((state = hmacopen(ix2alg[ix], key, len)) == NULL) +CODE: + if (items > 0) { + key = (UCHR *) (SvPVbyte(ST(items-1), len)); + } + if (hmacinit(&hmac, ix2alg[ix], key, len) == NULL) XSRETURN_UNDEF; for (i = 0; i < items - 1; i++) { data = (UCHR *) (SvPVbyte(ST(i), len)); while (len > MAX_WRITE_SIZE) { - hmacwrite(data, MAX_WRITE_SIZE << 3, state); + hmacwrite(data, MAX_WRITE_SIZE << 3, &hmac); data += MAX_WRITE_SIZE; len -= MAX_WRITE_SIZE; } - hmacwrite(data, len << 3, state); + hmacwrite(data, len << 3, &hmac); } - hmacfinish(state); + hmacfinish(&hmac); len = 0; if (ix % 3 == 0) { - result = (char *) digcpy(state->osha); - len = state->osha->digestlen; + result = (char *) hmacdigest(&hmac); + len = hmac.digestlen; } else if (ix % 3 == 1) - result = hmachex(state); + result = hmachex(&hmac); else - result = hmacbase64(state); - ST(0) = sv_2mortal(newSVpv(result, len)); - hmacclose(state); - XSRETURN(1); + result = hmacbase64(&hmac); + RETVAL = newSVpv(result, len); +OUTPUT: + RETVAL -void +int hashsize(self) SV * self ALIAS: @@ -177,14 +230,12 @@ ALIAS: Digest::SHA::algorithm = 1 PREINIT: SHA *state; - int result; -PPCODE: - if (!sv_isa(self, "Digest::SHA")) +CODE: + if ((state = getSHA(self)) == NULL) XSRETURN_UNDEF; - state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self)))); - result = ix ? state->alg : state->digestlen << 3; - ST(0) = sv_2mortal(newSViv(result)); - XSRETURN(1); + RETVAL = ix ? state->alg : state->digestlen << 3; +OUTPUT: + RETVAL void add(self, ...) @@ -195,9 +246,8 @@ PREINIT: STRLEN len; SHA *state; PPCODE: - if (!sv_isa(self, "Digest::SHA")) + if ((state = getSHA(self)) == NULL) XSRETURN_UNDEF; - state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self)))); for (i = 1; i < items; i++) { data = (UCHR *) (SvPVbyte(ST(i), len)); while (len > MAX_WRITE_SIZE) { @@ -209,78 +259,78 @@ PPCODE: } XSRETURN(1); -void +SV * digest(self) SV * self ALIAS: Digest::SHA::digest = 0 - Digest::SHA::Hexdigest = 1 - Digest::SHA::B64digest = 2 + Digest::SHA::hexdigest = 1 + Digest::SHA::b64digest = 2 PREINIT: STRLEN len; SHA *state; char *result; -PPCODE: - if (!sv_isa(self, "Digest::SHA")) +CODE: + if ((state = getSHA(self)) == NULL) XSRETURN_UNDEF; - state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self)))); shafinish(state); len = 0; if (ix == 0) { - result = (char *) digcpy(state); + result = (char *) shadigest(state); len = state->digestlen; } else if (ix == 1) result = shahex(state); else result = shabase64(state); - ST(0) = sv_2mortal(newSVpv(result, len)); + RETVAL = newSVpv(result, len); sharewind(state); - XSRETURN(1); +OUTPUT: + RETVAL -void +SV * _getstate(self) SV * self PREINIT: SHA *state; UCHR buf[256]; UCHR *ptr = buf; -PPCODE: - if (!sv_isa(self, "Digest::SHA")) +CODE: + if ((state = getSHA(self)) == NULL) XSRETURN_UNDEF; - state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self)))); - memcpy(ptr, digcpy(state), state->alg <= SHA256 ? 32 : 64); + Copy(digcpy(state), ptr, state->alg <= SHA256 ? 32 : 64, UCHR); ptr += state->alg <= SHA256 ? 32 : 64; - memcpy(ptr, state->block, state->alg <= SHA256 ? 64 : 128); + Copy(state->block, ptr, state->alg <= SHA256 ? 64 : 128, UCHR); ptr += state->alg <= SHA256 ? 64 : 128; ptr = w32mem(ptr, state->blockcnt); ptr = w32mem(ptr, state->lenhh); ptr = w32mem(ptr, state->lenhl); ptr = w32mem(ptr, state->lenlh); ptr = w32mem(ptr, state->lenll); - ST(0) = sv_2mortal(newSVpv((char *) buf, ptr - buf)); - XSRETURN(1); + RETVAL = newSVpv((char *) buf, ptr - buf); +OUTPUT: + RETVAL void -_putstate(self, ...) +_putstate(self, packed_state) SV * self + SV * packed_state PREINIT: UINT bc; STRLEN len; SHA *state; UCHR *data; PPCODE: - if (!sv_isa(self, "Digest::SHA")) + if ((state = getSHA(self)) == NULL) XSRETURN_UNDEF; - state = INT2PTR(SHA *, SvIV(SvRV(SvRV(self)))); - data = (UCHR *) SvPV(ST(1), len); + data = (UCHR *) SvPV(packed_state, len); if (len != (state->alg <= SHA256 ? 116 : 212)) XSRETURN_UNDEF; data = statecpy(state, data); - memcpy(state->block, data, state->blocksize >> 3); + Copy(data, state->block, state->blocksize >> 3, UCHR); data += (state->blocksize >> 3); bc = memw32(data), data += 4; - if (bc >= (state->alg <= SHA256 ? 512 : 1024)) + if (bc >= (state->alg <= SHA256 ? 512U : 1024U)) XSRETURN_UNDEF; state->blockcnt = bc; state->lenhh = memw32(data), data += 4; @@ -288,3 +338,63 @@ PPCODE: state->lenlh = memw32(data), data += 4; state->lenll = memw32(data); XSRETURN(1); + +void +_addfilebin(self, f) + SV * self + PerlIO * f +PREINIT: + SHA *state; + int n; + UCHR in[IO_BUFFER_SIZE]; +PPCODE: + if (!f || (state = getSHA(self)) == NULL) + XSRETURN_UNDEF; + while ((n = PerlIO_read(f, in, sizeof(in))) > 0) + shawrite(in, n << 3, state); + XSRETURN(1); + +void +_addfileuniv(self, f) + SV * self + PerlIO * f +PREINIT: + char c; + int n; + int cr = 0; + UCHR *src, *dst; + UCHR in[IO_BUFFER_SIZE+1]; + SHA *state; +PPCODE: + if (!f || (state = getSHA(self)) == NULL) + XSRETURN_UNDEF; + while ((n = PerlIO_read(f, in+1, IO_BUFFER_SIZE)) > 0) { + for (dst = in, src = in + 1; n; n--) { + c = *src++; + if (!cr) { + if (c == '\015') + cr = 1; + else + *dst++ = c; + } + else { + if (c == '\015') + *dst++ = '\012'; + else if (c == '\012') { + *dst++ = '\012'; + cr = 0; + } + else { + *dst++ = '\012'; + *dst++ = c; + cr = 0; + } + } + } + shawrite(in, (dst - in) << 3, state); + } + if (cr) { + in[0] = '\012'; + shawrite(in, 1 << 3, state); + } + XSRETURN(1); |