summaryrefslogtreecommitdiff
path: root/cpan/Digest-SHA/SHA.xs
diff options
context:
space:
mode:
authorChris 'BinGOs' Williams <chris@bingosnet.co.uk>2014-06-01 11:29:00 +0100
committerChris 'BinGOs' Williams <chris@bingosnet.co.uk>2014-06-01 11:29:00 +0100
commit207902b174bce23e6a15fc8e1c84389928c3db35 (patch)
treee249ccee2566e8f2b7283149bd13f699cbb46c0b /cpan/Digest-SHA/SHA.xs
parentd5e64588cb11db6bd730a216490fb0402b21eb07 (diff)
downloadperl-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.xs270
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);