#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <err.h>
#include <sys/param.h>
/* cc strlcpy_test.c -pipe -O2 -o strlcpy_test && ./strlcpy_testfast */
/*
* Copy string src to buffer dst of size dsize. At most dsize-1
* chars will be copied. Always NUL terminates (unless dsize == 0).
* Returns strlen(src); if retval >= dsize, truncation occurred.
*/
static size_t
strlcpy0(char *dst, const char *src, size_t dsize)
{
const char *osrc = src;
size_t nleft = dsize;
/* Copy as many bytes as will fit. */
if (nleft != 0) {
while (--nleft != 0) {
if ((*dst++ = *src++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src. */
if (nleft == 0) {
if (dsize != 0)
*dst = '\0'; /* NUL-terminate dst */
while (*src++)
;
}
return(src - osrc - 1); /* count does not include NUL */
}
static size_t
strlcpy3(char *dst, const char *src, size_t dsize)
{
const char *osrc = src;
size_t nleft = dsize;
if (nleft != 0) {
/* Copy as many bytes as will fit. */
while (--nleft != 0)
if ((*dst++ = *src++) == '\0')
return(src - osrc - 1);
*dst = '\0';
}
/* Not enough room in dst, traverse rest of src. */
while (*src++)
;
return(src - osrc - 1); /* count does not include NUL */
}
static size_t
strlcpy4(char dst[], const char src[], size_t dsize)
{
const char *osrc = src;
size_t nleft = dsize;
if (nleft != 0) {
if (--nleft == 0) {
*dst = '\0'; /* NUL-terminate dst */
if (*src == '\0')
return 0;
} else {
/* Copy as many bytes as will fit. */
if ((*dst = *src) == '\0')
return 0;
while (--nleft != 0)
if ((*++dst = *++src) == '\0')
return(src - osrc);
dst[1] = '\0'; /* NUL-terminate dst */
}
} else if (*src == '\0')
return 0;
/* Not enough room in dst, traverse rest of src. */
while (*++src)
;
return(src - osrc); /* count does not include NUL */
}
int main()
{
long double cpu_time_used;
size_t y;
struct timespec tv_start, tv_end;
char *buffer, *buffer2;
size_t n = 50000;
size_t m = n + 50;
buffer = malloc(m);
if (buffer == NULL) err(1, "malloc");
buffer2 = malloc(n);
if (buffer2 == NULL) err(1, "malloc");
/* no intermediate '\0' */
for (y = 0; y < m; ++y)
buffer[y] = arc4random_uniform(255) + 1;
buffer[m - 1] = '\0';
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_start);
strlcpy(buffer2, buffer, n);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_end);
cpu_time_used =
(long double) (tv_end.tv_sec - tv_start.tv_sec) +
(long double) (tv_end.tv_nsec - tv_start.tv_nsec) /
(long double) 1000000000;
printf("\n\nstrlcpy\n");
printf("time = %.9Lf\n\n\n", cpu_time_used);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_start);
strlcpy0(buffer2, buffer, n);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_end);
cpu_time_used =
(long double) (tv_end.tv_sec - tv_start.tv_sec) +
(long double) (tv_end.tv_nsec - tv_start.tv_nsec) /
(long double) 1000000000;
printf("\n\nstrlcpy0\n");
printf("time = %.9Lf\n\n\n", cpu_time_used);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_start);
strlcpy3(buffer2, buffer, n);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_end);
cpu_time_used =
(long double) (tv_end.tv_sec - tv_start.tv_sec) +
(long double) (tv_end.tv_nsec - tv_start.tv_nsec) /
(long double) 1000000000;
printf("\n\nstrlcpy3\n");
printf("time = %.9Lf\n\n\n", cpu_time_used);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_start);
strlcpy4(buffer2, buffer, n);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv_end);
cpu_time_used =
(long double) (tv_end.tv_sec - tv_start.tv_sec) +
(long double) (tv_end.tv_nsec - tv_start.tv_nsec) /
(long double) 1000000000;
printf("\n\nstrlcpy4\n");
printf("time = %.9Lf\n\n\n", cpu_time_used);
return 0;
}
I suppose this strlcpy4 without a goto is more elegant
-Luke
On Tue, Jun 30, 2020 at 10:07 PM Luke Small <lukensmall@gmail.com> wrote:
> I made it SUPER easy to test my assertion. The code is there. No
> configuration needed.
>
> On Tue, Jun 30, 2020 at 9:59 PM Theo de Raadt <deraadt@openbsd.org> wrote:
>
>> Luke Small <lukensmall@gmail.com> wrote:
>>
>> > So did you run the program on one of those?
>>
>> Why would I?
>>
>> i see a sales pitch
>>
>> and i go BULLSHIT
>>
>> and I'm done
>>
>> --
> -Luke
>
No comments:
Post a Comment