NAME

Crypt::SecretBuffer::Span - Prevent accidentally leaking a string of sensitive data

SYNOPSIS

use Crypt::SecretBuffer;
my $buf= Crypt::SecretBuffer->new->load_file("secrets.conf");

# Create a span, linked to $buf
my $s= $buf->span->utf8;

# Trim leading whitespace
$s->ltrim(qr/[\s]+/);

# Try parsing a '[' from the current position
if ($s->parse('[')) {
  # start of a INI-style "[header]"
  $header= $s->parse(qr/[^]\n]+/);  # capture until ']' or end of line
  
  $s->parse(']')
    or die "Didn't find ']' at end of header";

  $s->ltrim(qr/[\s]+/);
}

DESCRIPTION

This module represents a span of bytes in a Crypt::SecretBuffer, optionally with a character encoding. The methods on this object inspect the bytes of the SecretBuffer to alter the byte range or return new Span objects for sub-ranges. When you've narrowed-in on the data you want, you can extract it to another SecretBuffer object or a non-secret scalar using "copy_to".

This module provides some basic parsing ability for SecretBuffer text. While the "right tool for the job" would normally be Perl's regex engine, I have found no practical way to apply regexes to the buffer without it getting copied into global scalars, which would defeat the purpose of SecretBuffer. https://www.perlmonks.org/?node_id=11166676.

CONSTRUCTORS

new

$span= Crypt::SecretBuffer::Span->new(%attributes);

The only required attribute is buf. pos and lim will default to the length of the buffer, and encoding defaults to ISO8859_1 which treats each byte as an 8-bit unicode codepoint.

If called as a method on an object, this behaves the same as "clone".

clone

$span= $span->clone(%attributes);

Create a new span that inherits pos, lim, buf, and encoding from the first span if they weren't overridden in the attributes.

subspan

$span= $span->subspan($pos, $len);
$span= $span->subspan(pos => $pos, lim => $lim);

Like clone, but $pos and $lim (and negative $len values) are relative to the current span instead of absolute offsets into the buffer.

ATTRIBUTES

buf

The SecretBuffer this span refers to. Spans hold a strong reference to the buffer.

buffer

Alias for buf.

pos

The parse position. This is a byte offset within the SecretBuffer, even when using a multibyte encoding. This is never less than zero.

len

The count of bytes in this span. This is never less than zero, and will never refer past the end of the buffer unless you alter the buffer length.

length

Alias for len.

lim

The "limit" (one-beyond-the-end) position, equal to pos + len. This will never be greater than the length of the buffer unless you alter the buffer length.

encoding

Read-only; this determines how characters will be iterated within the SecretBuffer. This carries over to Span objects created from this span. See "Character Encodings" in Crypt::SecretBuffer.

METHODS

parse

$span= $span->parse($pattern);
$span= $span->parse($pattern, $flags=0);

If the current span begins with $pattern, return the span describing that pattern and advance "pos" to the end of that match. If not, return undef and pos is unchanged. See "Match Flags" in Crypt::SecretBuffer for the list of flags.

rparse

Alias for parse($pattern, MATCH_REVERSE). It parses and removes backward from the end of the span.

trim

$span->trim->...
$span->trim($pattern)->...
$span->trim($pattern, $flags)->...

Remove $pattern from the start and end of the Span. Returns the same Span object, for chaining. If you need to know how much was removed, use parse/rparse instead. Note that this only removes the pattern once, unless you provide the MATCH_MULTI flag or specify '+' on the end of your regex.

The default pattern is qr/[\s]+/.

See "Match Flags" in Crypt::SecretBuffer for the list of flags.

ltrim

Only remove from the start of the Span

rtrim

Only remove from the end of the Span

starts_with

$bool= $span->starts_with($pattern);

Return a boolean of whether $pattern matches at the start of the string.

ends_with

$bool= $span->ends_with($pattern);

Return a boolean of whether $pattern matches at the end of the string.

scan

$span= $span->scan($pattern, $flags=0);

Look for the first occurrence of a pattern in this Span. Return a new Span describing where it was found. The current Span is unchanged. See "Match Flags" in Crypt::SecretBuffer for the list of flags.

copy

copy_to

$secret= $span->copy(%options);
$span->copy_to($scalar_or_secret, %options);

Copy the current span of bytes. copy returns a new SecretBuffer object. copy_to writes into an existing buffer, which can be either a SecretBuffer or a scalar for non-secrets. There is intentionally not a method to return a scalar, to avoid easily leaking secrets.

Options:

encoding => $encoding

Encode bytes/characters written into the destination using the specified encoding. The bytes/characters are read from the current buffer using the Span's encoding attribute. The default is to assume the same destination encoding as the source and copy the bytes literally, *unless* the destination is a Perl scalar and the source encoding was a type of unicode, in which case the default is to copy as Perl "wide characters" (which is internally UTF-8). But, if you specify UTF-8 here, you will instead receive bytes of UTF-8 rather than perl wide characters.

VERSION

version 0.008

AUTHOR

Michael Conrad <mike@nrdvana.net>

COPYRIGHT AND LICENSE

This software is copyright (c) 2025 by Michael Conrad.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.