Improve standard compliance for memset_s() and abort_handler_s().
abort_handler_s() currently simply calls abort(), though the standard specifies more: "Writes an implementation-defined message to stderr which must include the string pointed to by msg and calls abort()." memset_s() is missing error condition "n > smax", and does not invoke the constraint handler after filling the buffer: "following errors are detected at runtime and call the currently installed constraint handler function after storing ch in every location of the destination range [dest, dest+destsz) if dest and destsz are themselves valid", one of the errors is "n > smax" itself. Submitted by: Yuri Pankov <yuripv@gmx.com> MFC after: 1 week Differential revision: https://reviews.freebsd.org/D11991
This commit is contained in:
parent
6fe9e5b821
commit
25b73e6327
@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
#include "libc_private.h"
|
||||
|
||||
@ -81,10 +83,14 @@ __throw_constraint_handler_s(const char * restrict msg, errno_t error)
|
||||
}
|
||||
|
||||
void
|
||||
abort_handler_s(const char * restrict msg __unused,
|
||||
void * restrict ptr __unused, errno_t error __unused)
|
||||
abort_handler_s(const char * restrict msg, void * restrict ptr __unused,
|
||||
errno_t error __unused)
|
||||
{
|
||||
static const char ahs[] = "abort_handler_s : ";
|
||||
|
||||
(void) _write(STDERR_FILENO, ahs, sizeof(ahs) - 1);
|
||||
(void) _write(STDERR_FILENO, msg, strlen(msg));
|
||||
(void) _write(STDERR_FILENO, "\n", 1);
|
||||
abort();
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ memset_s(void *s, rsize_t smax, int c, rsize_t n)
|
||||
volatile unsigned char *dst;
|
||||
|
||||
ret = EINVAL;
|
||||
lim = smax;
|
||||
lim = n < smax ? n : smax;
|
||||
v = (unsigned char)c;
|
||||
dst = (unsigned char *)s;
|
||||
if (s == NULL) {
|
||||
@ -53,11 +53,14 @@ memset_s(void *s, rsize_t smax, int c, rsize_t n)
|
||||
} else if (n > RSIZE_MAX) {
|
||||
__throw_constraint_handler_s("memset_s : n > RSIZE_MAX", ret);
|
||||
} else {
|
||||
if (n < smax)
|
||||
lim = n;
|
||||
while (lim > 0)
|
||||
dst[--lim] = v;
|
||||
ret = 0;
|
||||
if (n > smax) {
|
||||
__throw_constraint_handler_s("memset_s : n > smax",
|
||||
ret);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -109,13 +109,18 @@ ATF_TC_BODY(n_lt_smax, tc)
|
||||
assert(b[2] == 3);
|
||||
}
|
||||
|
||||
/* n > smax */
|
||||
/* n > smax, handler */
|
||||
ATF_TC_WITHOUT_HEAD(n_gt_smax);
|
||||
ATF_TC_BODY(n_gt_smax, tc)
|
||||
{
|
||||
char b[3] = {1, 2, 3};
|
||||
|
||||
assert(memset_s(&b[0], 1, 9, 3) == 0);
|
||||
e = 0;
|
||||
m = NULL;
|
||||
set_constraint_handler_s(h);
|
||||
assert(memset_s(&b[0], 1, 9, 3) != 0);
|
||||
assert(e > 0);
|
||||
assert(strcmp(m, "memset_s : n > smax") == 0);
|
||||
assert(b[0] == 9);
|
||||
assert(b[1] == 2);
|
||||
assert(b[2] == 3);
|
||||
|
Loading…
x
Reference in New Issue
Block a user