X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/cc448ceab170493a35039184f4f85054a8ddf971..32da1f0cbb3039b18da95a780824c723ee95d127:/util.c diff --git a/util.c b/util.c index 5d2d1ba..5989a58 100644 --- a/util.c +++ b/util.c @@ -542,55 +542,68 @@ Free_t Perl_mfree (Malloc_t where) #define DELIMCPY_OUT_OF_BOUNDS_RET I32_MAX /* -=for apidoc_section String Handling +=for apidoc_section $string =for apidoc delimcpy_no_escape Copy a source buffer to a destination buffer, stopping at (but not including) -the first occurrence of the delimiter byte C, in the source. The source -is the bytes between C and C inclusive. The dest is C -through C. +the first occurrence in the source of the delimiter byte, C. The source +is the bytes between S and C - 1>. Similarly, the dest is +C up to C. -Nothing is copied beyond what fits between C through C. If C -doesn't occur in the source buffer, as much of the source as will fit is copied -to the destination. +The number of bytes copied is written to C<*retlen>. -The actual number of bytes copied is written to C<*retlen>. +Returns the position of C in the C buffer, but if there is no +such occurrence before C, then C is returned, and the entire +buffer S .. C - 1> is copied. If there is room in the destination available after the copy, an extra -terminating safety NUL byte is written (not included in the returned length). +terminating safety C byte is appended (not included in the returned +length). + +The error case is if the destination buffer is not large enough to accommodate +everything that should be copied. In this situation, a value larger than +S - C> is written to C<*retlen>, and as much of the source as +fits will be written to the destination. Not having room for the safety C +is not considered an error. =cut */ char * -Perl_delimcpy_no_escape(char *to, const char *toend, const char *from, - const char *fromend, int delim, I32 *retlen) +Perl_delimcpy_no_escape(char *to, const char *to_end, + const char *from, const char *from_end, + const int delim, I32 *retlen) { const char * delim_pos; - Ptrdiff_t to_len = toend - to; - - /* Only use the minimum of the available source/dest */ - Ptrdiff_t copy_len = MIN(fromend - from, to_len); + Ptrdiff_t from_len = from_end - from; + Ptrdiff_t to_len = to_end - to; + SSize_t copy_len; PERL_ARGS_ASSERT_DELIMCPY_NO_ESCAPE; - assert(copy_len >= 0); + assert(from_len >= 0); + assert(to_len >= 0); - /* Look for the first delimiter in the portion of the source we are allowed - * to look at (determined by the input bounds). */ - delim_pos = (const char *) memchr(from, delim, copy_len); - if (delim_pos) { - copy_len = delim_pos - from; - } /* else didn't find it: copy all of the source permitted */ + /* Look for the first delimiter in the source */ + delim_pos = (const char *) memchr(from, delim, from_len); - Copy(from, to, copy_len, char); + /* Copy up to where the delimiter was found, or the entire buffer if not + * found */ + copy_len = (delim_pos) ? delim_pos - from : from_len; - if (retlen) { - *retlen = copy_len; + /* If not enough room, copy as much as can fit, and set error return */ + if (copy_len > to_len) { + Copy(from, to, to_len, char); + *retlen = DELIMCPY_OUT_OF_BOUNDS_RET; } + else { + Copy(from, to, copy_len, char); - /* If there is extra space available, add a trailing NUL */ - if (copy_len < to_len) { - to[copy_len] = '\0'; + /* If there is extra space available, add a trailing NUL */ + if (copy_len < to_len) { + to[copy_len] = '\0'; + } + + *retlen = copy_len; } return (char *) from + copy_len; @@ -1288,7 +1301,7 @@ Perl_cntrl_to_mnemonic(const U8 c) /* copy a string to a safe spot */ /* -=for apidoc_section String Handling +=for apidoc_section $string =for apidoc savepv Perl's version of C. Returns a pointer to a newly allocated @@ -1495,7 +1508,7 @@ Perl_form_nocontext(const char* pat, ...) #endif /* PERL_IMPLICIT_CONTEXT */ /* -=for apidoc_section Display and Dump functions +=for apidoc_section $display =for apidoc form =for apidoc_item form_nocontext @@ -1783,7 +1796,7 @@ Perl_write_to_stderr(pTHX_ SV* msv) } /* -=for apidoc_section Warning and Dieing +=for apidoc_section $warning */ /* Common code used in dieing and warning */ @@ -2435,7 +2448,7 @@ S_env_alloc(void *current, Size_t l1, Size_t l2, Size_t l3, Size_t size) # if !defined(WIN32) && !defined(NETWARE) /* -=for apidoc_section Utility Functions +=for apidoc_section $utility =for apidoc my_setenv A wrapper for the C library L. Don't use the latter, as the perl @@ -3022,7 +3035,7 @@ dup2(int oldfd, int newfd) #ifdef HAS_SIGACTION /* -=for apidoc_section Signals +=for apidoc_section $signals =for apidoc rsignal A wrapper for the C library L. Don't use the latter, as the Perl @@ -3933,7 +3946,7 @@ Perl_init_tm(pTHX_ struct tm *ptm) /* see mktime, strftime and asctime */ } /* -=for apidoc_section Time +=for apidoc_section $time =for apidoc mini_mktime normalise S> values without the localtime() semantics (and overhead) of mktime(). @@ -4133,7 +4146,7 @@ Perl_my_strftime(pTHX_ const char *fmt, int sec, int min, int hour, int mday, in #ifdef HAS_STRFTIME /* -=for apidoc_section Time +=for apidoc_section $time =for apidoc my_strftime strftime(), but with a different API so that the return value is a pointer to the formatted result (which MUST be arranged to be FREED BY THE @@ -4242,7 +4255,7 @@ mini_mktime() overwrites them (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) /* -=for apidoc_section Utility Functions +=for apidoc_section $utility =for apidoc getcwd_sv @@ -5150,7 +5163,7 @@ Perl_mem_log_del_sv(const SV *sv, #endif /* PERL_MEM_LOG */ /* -=for apidoc_section String Handling +=for apidoc_section $string =for apidoc quadmath_format_valid C is very strict about its C string and will @@ -6327,7 +6340,7 @@ static void atos_symbolize(atos_context* ctx, #endif /* #ifdef PERL_DARWIN */ /* -=for apidoc_section Display and Dump functions +=for apidoc_section $debugging =for apidoc get_c_backtrace Collects the backtrace (aka "stacktrace") into a single linear @@ -6579,7 +6592,6 @@ Deallocates a backtrace received from get_c_backtrace. */ /* -=for apidoc_section Display and Dump functions =for apidoc get_c_backtrace_dump Returns a SV containing a dump of C frames of the call stack, skipping