view release on metacpan or search on metacpan
SecretBuffer.xs view on Meta::CPAN
void
new(...)
ALIAS:
Crypt::SecretBuffer::Exports::secret = 1
Crypt::SecretBuffer::Exports::secret_buffer = 2
INIT:
SV *buf_ref= NULL;
secret_buffer *buf= secret_buffer_new(0, &buf_ref);
int i, next_arg= ix == 0? 1 : 0;
PPCODE:
if (items - next_arg == 1) {
secret_buffer_splice_sv(buf, 0, 0, ST(next_arg));
}
else {
if ((items - next_arg) & 1)
croak("Odd number of arguments; expected (key => value) pairs");
for (i= next_arg; i < items-1; i += 2) {
SV *key= ST(i), *val= ST(i+1);
{
dSP;
SecretBuffer.xs view on Meta::CPAN
assign = 1
INIT:
int i;
size_t from_ofs= (ix? 0 : buf->len), len_sum= 0;
U8 *write_pos;
secret_buffer_byte_range stack_ranges[16], *ranges= stack_ranges;
if ((items-1) > 16) {
Newx(ranges, (items-1), secret_buffer_byte_range);
SAVEFREEPV(ranges);
}
PPCODE:
for (i= 0; i < items-1; i++) {
ranges[i].ptr= secret_buffer_SvPVbyte(ST(i+1), &ranges[i].len);
len_sum += ranges[i].len;
}
secret_buffer_set_len(buf, from_ofs + len_sum);
write_pos= buf->data + from_ofs;
for (i= 0; i < items-1; i++) {
memcpy(write_pos, ranges[i].ptr, ranges[i].len);
write_pos += ranges[i].len;
}
XSRETURN(1); /* return self for chaining */
void
length(buf, val=NULL)
auto_secret_buffer buf
SV *val
ALIAS:
len = 1
PPCODE:
if (val) { /* writing */
IV ival= SvIV(val);
if (ival < 0) ival= 0;
secret_buffer_set_len(buf, ival);
/* return self, for chaining */
}
else /* reading */
ST(0)= sv_2mortal(newSViv(buf->len));
XSRETURN(1);
void
capacity(buf, val=NULL, flags= 0)
auto_secret_buffer buf
SV *val
secret_buffer_alloc_flags flags
PPCODE:
if (val) { /* wiritng */
IV ival= SvIV(val);
if (ival < 0) ival= 0;
if (flags & SECRET_BUFFER_AT_LEAST)
secret_buffer_alloc_at_least(buf, ival);
else
secret_buffer_realloc(buf, ival);
/* return self, for chaining */
}
else /* reading */
ST(0)= sv_2mortal(newSViv(buf->capacity));
XSRETURN(1);
void
clear(buf)
auto_secret_buffer buf
PPCODE:
secret_buffer_realloc(buf, 0);
XSRETURN(1); /* self, for chaining */
IV
index(buf, pattern, ofs_sv= &PL_sv_undef)
secret_buffer *buf
SV *pattern
SV *ofs_sv
ALIAS:
rindex = 1
SecretBuffer.xs view on Meta::CPAN
secret_buffer_parse parse;
// lim was captured as an SV so that undef can be used to indicate
// end of the buffer.
IV len= !SvOK(len_sv)? buf->len : SvIV(len_sv);
ofs= normalize_offset(ofs, buf->len);
if (!secret_buffer_parse_init(&parse, buf,
ofs, ofs + normalize_offset(len, buf->len - ofs),
(flags & SECRET_BUFFER_ENCODING_MASK)
))
croak("%s", parse.error);
PPCODE:
if (secret_buffer_match(&parse, pattern, flags)) {
PUSHs(sv_2mortal(newSViv(parse.pos - (U8*) buf->data)));
PUSHs(sv_2mortal(newSViv(parse.lim - parse.pos)));
}
else if (parse.error)
croak("%s", parse.error);
void
splice(buf, ofs, len, replacement)
secret_buffer *buf
IV ofs
IV len
SV *replacement
PPCODE:
/* normalize negative offset, and clamp to valid range */
ofs= normalize_offset(ofs, buf->len);
/* normalize negative count, and clamp to valid range */
len= normalize_offset(len, buf->len - ofs);
secret_buffer_splice_sv(buf, ofs, len, replacement);
XSRETURN(1); /* return $self */
void
substr(buf, ofs, count_sv=NULL, replacement=NULL)
secret_buffer *buf
IV ofs
SV *count_sv
SV *replacement
INIT:
unsigned char *sub_start;
secret_buffer *sub_buf= NULL;
SV *sub_ref= NULL;
IV count= count_sv? SvIV(count_sv) : buf->len;
PPCODE:
/* normalize negative offset, and clamp to valid range */
ofs= normalize_offset(ofs, buf->len);
/* normalize negative count, and clamp to valid range */
count= normalize_offset(count, buf->len - ofs);
sub_start= (unsigned char*) buf->data + ofs;
/* If called in non-void context, construct new secret from this range */
if (GIMME_V != G_VOID) {
SV **el;
sub_buf= secret_buffer_new(count, &sub_ref);
if (count) {
SecretBuffer.xs view on Meta::CPAN
XSRETURN(0);
else {
ST(0)= sub_ref; /* already mortal */
XSRETURN(1);
}
void
append_asn1_der_length(buf, val)
secret_buffer *buf
UV val
PPCODE:
secret_buffer_append_uv_asn1_der_length(buf, val);
void
append_base128le(buf, val)
secret_buffer *buf
UV val
PPCODE:
secret_buffer_append_uv_base128le(buf, val);
void
append_base128be(buf, val)
secret_buffer *buf
UV val
PPCODE:
secret_buffer_append_uv_base128be(buf, val);
void
append_lenprefixed(buf, ...)
secret_buffer *buf
INIT:
size_t bytes_needed= 0;
IV i;
PPCODE:
/* Add up all the lengths and over-estimate 9 bytes for each length specifier */
for (i= 1; i < items; i++) {
STRLEN len;
secret_buffer_SvPVbyte(ST(i), &len);
bytes_needed += 9 + len;
}
/* ensure space with one reallocation */
secret_buffer_alloc_at_least(buf, buf->len + bytes_needed);
/* append each length and span to the buffer */
for (i= 1; i < items; i++) {
SecretBuffer.xs view on Meta::CPAN
OUTPUT:
RETVAL
void
append_sysread(buf, handle, count)
auto_secret_buffer buf
PerlIO *handle
IV count
INIT:
IV got;
PPCODE:
got= secret_buffer_append_sysread(buf, handle, count);
if (got < 0)
XSRETURN_UNDEF;
else
PUSHs(sv_2mortal(newSViv(got)));
void
append_read(buf, handle, count)
auto_secret_buffer buf
PerlIO *handle
IV count
INIT:
int got;
PPCODE:
got= secret_buffer_append_read(buf, handle, count);
if (got < 0)
XSRETURN_UNDEF;
else
PUSHs(sv_2mortal(newSViv(got)));
void
_append_console_line(buf, handle)
auto_secret_buffer buf
PerlIO *handle
INIT:
int got;
PPCODE:
got= secret_buffer_append_console_line(buf, handle);
ST(0)= got == SECRET_BUFFER_GOTLINE? &PL_sv_yes
: got == SECRET_BUFFER_EOF? &PL_sv_no
: &PL_sv_undef;
XSRETURN(1);
void
syswrite(buf, io, count=buf->len, ofs=0)
secret_buffer *buf
PerlIO *io
IV ofs
IV count
INIT:
IV wrote;
PPCODE:
wrote= secret_buffer_syswrite(buf, io, ofs, count);
ST(0)= (wrote < 0)? &PL_sv_undef : sv_2mortal(newSViv(wrote));
XSRETURN(1);
void
write_async(buf, io, count=buf->len, ofs=0)
secret_buffer *buf
PerlIO *io
IV ofs
IV count
INIT:
IV wrote;
SV *ref_out= NULL;
PPCODE:
wrote= secret_buffer_write_async(buf, io, ofs, count, GIMME_V == G_VOID? NULL : &ref_out);
/* wrote == 0 means that it supplied a result promise object, which is already mortal.
* but avoid creating one when called in void context. */
ST(0)= wrote? sv_2mortal(newSViv(wrote)) : ref_out? ref_out : &PL_sv_undef;
XSRETURN(1);
void
stringify(buf, ...)
auto_secret_buffer buf
INIT:
SV **field= hv_fetch((HV*)SvRV(ST(0)), "stringify_mask", 14, 0);
PPCODE:
if (!field || !*field) {
ST(0)= sv_2mortal(newSVpvn("[REDACTED]", 10));
} else if (SvOK(*field)) {
ST(0)= *field;
} else {
ST(0)= secret_buffer_get_stringify_sv(buf);
}
XSRETURN(1);
void
unmask_to(buf, coderef)
secret_buffer *buf
SV *coderef
INIT:
int count= 0;
PPCODE:
PUSHMARK(SP);
EXTEND(SP, 1);
PUSHs(secret_buffer_get_stringify_sv(buf));
PUTBACK;
count= call_sv(coderef, GIMME_V);
SPAGAIN;
XSRETURN(count);
bool
_can_count_copies_in_process_memory()
SecretBuffer.xs view on Meta::CPAN
RETVAL
MODULE = Crypt::SecretBuffer PACKAGE = Crypt::SecretBuffer::Exports
void
unmask_secrets_to(coderef, ...)
SV *coderef
INIT:
int count= 0, i;
secret_buffer *buf= NULL;
PPCODE:
PUSHMARK(SP);
EXTEND(SP, items);
for (i= 1; i < items; i++) {
if (SvOK(ST(i)) && SvROK(ST(i)) && (buf= secret_buffer_from_magic(ST(i), 0)))
PUSHs(secret_buffer_get_stringify_sv(buf));
else
PUSHs(ST(i));
}
PUTBACK;
count= call_sv(coderef, GIMME_V);
SecretBuffer.xs view on Meta::CPAN
CODE:
RETVAL= sb_wait_fh_readable(aTHX_ handle, timeout_sv);
OUTPUT:
RETVAL
void
_debug_charset(cset)
secret_buffer_charset *cset
INIT:
HV *hv;
PPCODE:
PUSHs(sv_2mortal((SV*)newRV_noinc((SV*)(hv= newHV()))));
hv_stores(hv, "bitmap", newSVpvn((char*)cset->bitmap, sizeof(cset->bitmap)));
hv_stores(hv, "unicode_above_7F", newSViv(cset->unicode_above_7F));
MODULE = Crypt::SecretBuffer PACKAGE = Crypt::SecretBuffer::AsyncResult
void
wait(result, timeout=-1)
secret_buffer_async_result *result
NV timeout
INIT:
IV os_err, bytes_written;
PPCODE:
if (secret_buffer_async_result_recv(result, (IV)(timeout*1000), &bytes_written, &os_err)) {
EXTEND(sp, 2);
ST(0)= sv_2mortal(newSViv(bytes_written));
ST(1)= sv_2mortal(newSViv(os_err));
XSRETURN(2);
} else {
XSRETURN(0);
}
MODULE = Crypt::SecretBuffer PACKAGE = Crypt::SecretBuffer::ConsoleState
SecretBuffer.xs view on Meta::CPAN
else if (len == 12 && memcmp(name, "auto_restore", 12) == 0) {
if (SvOK(val)) auto_restore= val;
}
else {
croak("Unknown option '%s'", name);
}
}
}
if (!handle)
croak("'handle' is required");
PPCODE:
ST(0)= &PL_sv_undef;
/* if it fails to initialize, return undef for 'maybe_new', else die */
if (!sb_console_state_init(aTHX_ &cstate, handle)) {
if (ix == 0)
croak("Can't read console/tty state");
XSRETURN(1);
}
if (auto_restore)
cstate.auto_restore= SvTRUE(auto_restore);
if (set_echo) {
SecretBuffer.xs view on Meta::CPAN
: NULL;
secret_buffer *buf= secret_buffer_from_magic(
buf_field? *buf_field : class_or_obj, SECRET_BUFFER_MAGIC_UNDEF_OK
);
bool subspan= span && ix >= 2;
IV base_pos= subspan? span->pos : 0;
IV pos=0, lim=0, len=0, base_lim=0;
int encoding= span? span->encoding : 0, i;
SV *encoding_sv= NULL;
bool have_pos= false, have_lim= false, have_len= false;
PPCODE:
//warn("items=%d span=%p buf=%p base_pos=%d", (int)items, span, buf, (int)base_pos);
// 3-argument form, only usable when first arg is a buffer or refs a buffer
if (buf && items >= 2 && looks_like_number(ST(1))) {
pos= SvIV(ST(1));
have_pos= true;
if (items >= 3 && SvOK(ST(2))) {
len= SvIV(ST(2));
have_len= true;
if (items >= 4) {
encoding_sv= ST(3);
SecretBuffer.xs view on Meta::CPAN
RETVAL
void
encoding(span, newval_sv= NULL)
secret_buffer_span *span
SV *newval_sv
INIT:
SV *enc_const;
AV *encodings= get_av("Crypt::SecretBuffer::_encodings", 0);
if (!encodings) croak("BUG");
PPCODE:
if (newval_sv)
if (!parse_encoding(aTHX_ newval_sv, &span->encoding))
croak("Invalid encoding");
enc_const= *av_fetch(encodings, span->encoding, 1);
if (!enc_const || !SvOK(enc_const))
croak("BUG");
PUSHs(enc_const);
const char *
last_error(span)
SecretBuffer.xs view on Meta::CPAN
set_up_us_the_bom(self)
SV *self
ALIAS:
consume_bom = 1
INIT:
secret_buffer_span *span= secret_buffer_span_from_magic(self, SECRET_BUFFER_MAGIC_OR_DIE);
secret_buffer_parse p;
if (!secret_buffer_parse_init_from_sv(&p, self))
croak("%s", p.error);
PERL_UNUSED_VAR(ix);
PPCODE:
if (p.lim - p.pos >= 3 && p.pos[0] == 0xEF && p.pos[1] == 0xBB && p.pos[2] == 0xBF) {
span->encoding= SECRET_BUFFER_ENCODING_UTF8;
span->pos += 3;
}
else if (p.lim - p.pos >= 2 && p.pos[0] == 0xFF && p.pos[1] == 0xFE) {
span->encoding= SECRET_BUFFER_ENCODING_UTF16LE;
span->pos += 2;
}
else if (p.lim - p.pos >= 2 && p.pos[0] == 0xFE && p.pos[1] == 0xFF) {
span->encoding= SECRET_BUFFER_ENCODING_UTF16BE;
SecretBuffer.xs view on Meta::CPAN
if (ret_type != 1 && parse.encoding == SECRET_BUFFER_ENCODING_BASE64)
croak("Cannot perform parse, trim, or scan on base64 (pos / lim of result would not be whole bytes)");
int op= (ix >> 8);
bool matched;
if (!pattern) {
if (op == 3 || op == 4 || op == 5)
pattern= get_sv("Crypt::SecretBuffer::Span::default_trim_regex", 0);
if (!pattern)
croak("pattern is required");
}
PPCODE:
matched= secret_buffer_match(&parse, pattern, flags);
if (parse.error)
croak("%s", parse.error);
switch (op) {
case 1: // parse
if (matched) span->pos= parse.lim - (U8*) buf->data;
break;
case 2: // rparse
if (matched) span->lim= parse.pos - (U8*) buf->data;
break;
SecretBuffer.xs view on Meta::CPAN
SV *self
IV count
INIT:
secret_buffer_span *span= secret_buffer_span_from_magic(self, SECRET_BUFFER_MAGIC_OR_DIE);
secret_buffer_parse p;
UV len;
size_t ofs;
/* treat an invalid span as a bug, rather than returning it to the user in the err_out param */
if (!secret_buffer_parse_init_from_sv(&p, self))
croak("%s", p.error);
PPCODE:
while (count && p.pos < p.lim) {
if (!secret_buffer_parse_uv_base128be(&p, &len)) {
span->last_error= p.error;
XSRETURN_EMPTY;
}
if (len > p.lim - p.pos) {
span->last_error= "Length exceeds end of Span";
XSRETURN_EMPTY;
}
ofs= p.pos - (U8*) p.sbuf->data;
SecretBuffer.xs view on Meta::CPAN
SV *self
ALIAS:
copy_to = 1
append_to = 2
INIT:
SV *dst_sv= NULL;
int next_arg, dst_encoding= -1;
secret_buffer_parse src;
if (!secret_buffer_parse_init_from_sv(&src, self))
croak("%s", src.error);
PPCODE:
if (ix > 0) { /* called as 'copy_to' or 'append_to' */
if (items < 2)
croak("Missing copy/append destination");
dst_sv= ST(1);
next_arg= 2;
}
else { /* called as 'copy' */
secret_buffer_new(0, &dst_sv);
next_arg= 1;
}