Crypt-SecretBuffer
view release on metacpan or search on metacpan
secret_buffer_parse_match_str.c view on Meta::CPAN
/* search_pos keeps track of where this iteration started, and next_search_pos
* may get set during the match to indicate we need to backtrack the parse->pos */
const U8 *search_pos= parse->pos, *next_char_pos;
U8 search_pos_bit= parse->pos_bit, next_char_pos_bit;
bool matched;
int cp= sb_parse_next_codepoint(parse);
#define SB_HANDLE_ENCODING_ERROR { \
if (!encoding_error) { \
encoding_error= true; \
/* record the location of the encoding error as if we stopped there */ \
ret_pos= parse->pos; \
ret_pos_bit= parse->pos_bit; \
ret_lim= parse->lim; \
ret_lim_bit= parse->lim_bit; \
if (!consttime) /* consttime keeps going */ \
break; \
} \
++parse->pos; /* ensure forward progress for consttime */ \
}
if (cp < 0) SB_HANDLE_ENCODING_ERROR
next_char_pos= parse->pos;
next_char_pos_bit= parse->pos_bit;
matched= cp == first_cp;
if ((matched || consttime) && pattern_len > 1) {
SB_PATTERN_EL_TYPE *pat_pos= pattern+1, *pat_lim= pattern + pattern_len;
const U8 *next_potential_pos= NULL; U8 next_potential_pos_bit= 0;
while (parse->pos < parse->lim && pat_pos < pat_lim) {
const U8 *at_pos= parse->pos; U8 at_pos_bit= parse->pos_bit;
cp= sb_parse_next_codepoint(parse);
if (cp < 0) SB_HANDLE_ENCODING_ERROR
/* speed up outer loop by checking for whether this character could be the start
of the next match */
if (cp == first_cp && !next_potential_pos) {
next_potential_pos= at_pos;
next_potential_pos_bit= at_pos_bit;
}
if (cp != *pat_pos) {
matched= false;
if (!consttime)
break;
}
++pat_pos;
}
if (pat_pos < pat_lim)
matched= false;
/* If not a match, backtrack to wherever the next match could start. */
if (!matched && next_potential_pos) {
parse->pos= next_potential_pos;
parse->pos_bit= next_potential_pos_bit;
}
}
#if 0
if (consttime) {
warn(" @%2d matched=%d parse->pos=%d real_search_pos=%d ret_pos=%d ret_lim=%d anchor_fail=%d",
(int)(search_pos-orig), (int)matched, (int)(parse->pos-orig), (int)(real_search_pos-orig),
(int)(ret_pos? ret_pos-orig : -1), (int)(ret_lim? ret_lim-orig : -1), (int)anchor_fail);
}
#endif
#undef SB_HANDLE_ENCODING_ERROR
/* Code below does not set return values unless `search_pos >= real_search_pos`
* so that the consttime busywork iterations don't change any return-value state.
*/
/* Found the goal? (match, or negated match) */
if (matched != negate) {
/* The desired (multi?)match begins here, unless it already began */
if (!ret_pos && search_pos >= real_search_pos) {
ret_pos= search_pos;
ret_pos_bit= search_pos_bit;
}
/* It also ends here if multi is false, unless already set */
if (!multi && !ret_lim && search_pos >= real_search_pos) {
/* negative matches end at the character following search_pos */
if (negate) {
ret_lim= next_char_pos;
ret_lim_bit= next_char_pos_bit;
} else {
ret_lim= parse->pos;
ret_lim_bit= parse->pos_bit;
}
if (!consttime || anchored)
break;
}
}
/* If not a match (or matches but negated) and the multi-match was started,
* search_pos is the end of the multi-match. */
else if (multi && ret_pos && !ret_lim) {
if (search_pos >= real_search_pos) {
ret_lim= search_pos;
ret_lim_bit= search_pos_bit;
if (!consttime)
break;
}
}
else if (anchored) { /* not our goal, anchored, and not multi-match */
if (!ret_pos) {
anchor_fail= true;
/* return essentially the original value of 'parse' */
ret_pos= search_pos;
ret_pos_bit= search_pos_bit;
ret_lim= parse->lim;
ret_lim_bit= parse->lim_bit;
}
/* only need to waste time if consttime with multiple matches */
if (!(consttime && multi))
break;
}
/* constant time iteration always resumes at the following character */
if (consttime) {
if (search_pos >= real_search_pos)
real_search_pos= parse->pos;
parse->pos= next_char_pos;
parse->pos_bit= next_char_pos_bit;
}
}
/* If loop exited due to end of input and multi-match was in progress, mark the end */
if (multi && ret_pos && !ret_lim) {
ret_lim= parse->lim;
ret_lim_bit= parse->lim_bit;
}
}
/* Else do the above in reverse from end of parse span */
secret_buffer_parse_match_str.c view on Meta::CPAN
int last_cp= pattern[pattern_len-1];
while (parse->pos < parse->lim) {
const U8 *search_lim= parse->lim, *next_char_lim;
U8 search_lim_bit= parse->lim_bit, next_char_lim_bit;
bool matched;
int cp= sb_parse_prev_codepoint(parse);
#define SB_HANDLE_ENCODING_ERROR { \
if (!encoding_error) { \
encoding_error= true; \
/* record the location of the encoding error as if we stopped there */ \
ret_pos= parse->pos; \
ret_pos_bit= parse->pos_bit; \
ret_lim= parse->lim; \
ret_lim_bit= parse->lim_bit; \
if (!consttime) /* consttime keeps going */ \
break; \
} \
--parse->lim; /* ensure progress for consttime */ \
}
if (cp < 0) SB_HANDLE_ENCODING_ERROR
next_char_lim= parse->lim;
next_char_lim_bit= parse->lim_bit;
matched= cp == last_cp;
if ((matched || consttime) && pattern_len > 1) {
SB_PATTERN_EL_TYPE *pat_lim= pattern + pattern_len - 1; /* final char already matched */
const U8 *next_potential_lim= NULL; U8 next_potential_lim_bit= 0;
while (parse->pos < parse->lim && pattern < pat_lim) {
const U8 *at_lim= parse->lim; U8 at_lim_bit= parse->lim_bit;
cp= sb_parse_prev_codepoint(parse);
if (cp < 0) SB_HANDLE_ENCODING_ERROR
/* if const time is not requested, speed up outer loop by checking for whether
* this character could be the start of the next match */
if (cp == last_cp && !next_potential_lim) {
next_potential_lim= at_lim;
next_potential_lim_bit= at_lim_bit;
}
if (cp != pat_lim[-1]) {
matched= false;
if (!consttime)
break;
}
--pat_lim;
}
if (pattern < pat_lim)
matched= false;
/* If not a match, backtrack to wherever the next match could start. */
if (!matched && next_potential_lim) {
parse->lim= next_potential_lim;
parse->lim_bit= next_potential_lim_bit;
}
}
#if 0
if (!anchored && !multi) {
warn(" @%2d matched=%d parse->lim=%d real_search_lim=%d ret_pos=%d ret_lim=%d anchor_fail=%d",
(int)(search_lim-orig-1), (int)matched, (int)(parse->lim-orig), (int)(real_search_lim-orig),
(int)(ret_pos? ret_pos-orig : -1), (int)(ret_lim? ret_lim-orig : -1), (int)anchor_fail);
}
#endif
#undef SB_HANDLE_ENCODING_ERROR
/* Code below does not set return values unless `search_pos >= real_search_pos`
* so that the consttime busywork iterations don't change any return-value state.
*/
/* Found the goal? (match, or negated match) */
if (matched != negate) {
/* The desired (multi?)match begins here, unless it already began */
if (!ret_lim && search_lim <= real_search_lim) {
ret_lim= search_lim;
ret_lim_bit= search_lim_bit;
}
/* It also ends here if multi is false, unless already set */
if (!multi && !ret_pos && search_lim <= real_search_lim) {
/* negative matches end at the character following search_pos */
if (negate) {
ret_pos= next_char_lim;
ret_pos_bit= next_char_lim_bit;
} else {
ret_pos= parse->lim;
ret_pos_bit= parse->lim_bit;
}
if (!consttime || anchored)
break;
}
}
/* If not a match (or matches but negated) and the multi-match was started,
* search_lim is the front of the multi-match. */
else if (multi && ret_lim && !ret_pos) {
if (search_lim <= real_search_lim) {
ret_pos= search_lim;
ret_pos_bit= search_lim_bit;
if (!consttime)
break;
}
}
else if (anchored) { /* not our goal, anchored, and not multi-match */
if (!ret_lim) {
anchor_fail= true;
/* return essentially the original value of 'parse' */
ret_lim= search_lim;
ret_lim_bit= search_lim_bit;
ret_pos= parse->pos;
ret_pos_bit= parse->pos_bit;
}
/* only need to waste time if consttime with multiple matches */
if (!(consttime && multi))
break;
}
/* constant time iteration always resumes at the following character */
if (consttime) {
if (search_lim <= real_search_lim)
real_search_lim= parse->lim;
parse->lim= next_char_lim;
parse->lim_bit= next_char_lim_bit;
}
}
/* If loop exited due to end of input and multi-match was in progress, mark the end */
if (multi && ret_lim && !ret_pos) {
ret_pos= parse->pos;
ret_pos_bit= parse->pos_bit;
}
}
/* If they are both set, overwrite parse and maybe return true.
( run in 0.904 second using v1.01-cache-2.11-cpan-39bf76dae61 )