FreeBSD/sbin/hastd/nv.c
/*
 * Validate correctness of the entire nv structure and all its elements.
 * If extrap is not NULL, store number of extra bytes at the end of the buffer.
 */
Validate correctness of the entire nv structure and all its elements.
If extrap is not NULL, store number of extra bytes at the end of the buffer.
Validate correctness of the entire nv structure and all its elements . If extrap is not NULL store number of extra bytes at the end of the buffer .
int
nv_validate(struct nv *nv, size_t *extrap)
{
	struct nvhdr *nvh;
	unsigned char *data, *ptr;
	size_t dsize, size, vsize;
	int error;
	if (nv == NULL) {
		errno = ENOMEM;
		return (-1);
	}
	NV_CHECK(nv);
	PJDLOG_ASSERT(nv->nv_error == 0);
	error = 0;
	ptr = ebuf_data(nv->nv_ebuf, &size);
	while (size > 0) {
		if (ptr[0] == '\0')
			break;
		if (size < sizeof(*nvh) + 2) {
			error = EINVAL;
			break;
		}
		nvh = (struct nvhdr *)ptr;
		if (size < NVH_HSIZE(nvh)) {
			error = EINVAL;
			break;
		}
		if (nvh->nvh_name[nvh->nvh_namesize - 1] != '\0') {
			error = EINVAL;
			break;
		}
		if (strlen(nvh->nvh_name) !=
		    (size_t)(nvh->nvh_namesize - 1)) {
			error = EINVAL;
			break;
		}
		if ((nvh->nvh_type & NV_TYPE_MASK) < NV_TYPE_FIRST ||
		    (nvh->nvh_type & NV_TYPE_MASK) > NV_TYPE_LAST) {
			error = EINVAL;
			break;
		}
		dsize = NVH_DSIZE(nvh);
		if (dsize == 0) {
			error = EINVAL;
			break;
		}
		if (size < NVH_SIZE(nvh)) {
			error = EINVAL;
			break;
		}
		vsize = 0;
		switch (nvh->nvh_type & NV_TYPE_MASK) {
		case NV_TYPE_INT8:
		case NV_TYPE_UINT8:
			if (vsize == 0)
				vsize = 1;
		case NV_TYPE_INT16:
		case NV_TYPE_UINT16:
			if (vsize == 0)
				vsize = 2;
		case NV_TYPE_INT32:
		case NV_TYPE_UINT32:
			if (vsize == 0)
				vsize = 4;
		case NV_TYPE_INT64:
		case NV_TYPE_UINT64:
			if (vsize == 0)
				vsize = 8;
			if (dsize != vsize) {
				error = EINVAL;
				break;
			}
			break;
		case NV_TYPE_INT8_ARRAY:
		case NV_TYPE_UINT8_ARRAY:
			break;
		case NV_TYPE_INT16_ARRAY:
		case NV_TYPE_UINT16_ARRAY:
			if (vsize == 0)
				vsize = 2;
		case NV_TYPE_INT32_ARRAY:
		case NV_TYPE_UINT32_ARRAY:
			if (vsize == 0)
				vsize = 4;
		case NV_TYPE_INT64_ARRAY:
		case NV_TYPE_UINT64_ARRAY:
			if (vsize == 0)
				vsize = 8;
			if ((dsize % vsize) != 0) {
				error = EINVAL;
				break;
			}
			break;
		case NV_TYPE_STRING:
			data = NVH_DATA(nvh);
			if (data[dsize - 1] != '\0') {
				error = EINVAL;
				break;
			}
			if (strlen((char *)data) != dsize - 1) {
				error = EINVAL;
				break;
			}
			break;
		default:
			PJDLOG_ABORT("invalid condition");
		}
		if (error != 0)
			break;
		ptr += NVH_SIZE(nvh);
		size -= NVH_SIZE(nvh);
	}
	if (error != 0) {
		errno = error;
		if (nv->nv_error == 0)
			nv->nv_error = error;
		return (-1);
	}
	if (extrap != NULL)
		*extrap = size;
	return (0);
}
int nv_validate ( struct nv * nv , size_t * extrap ) { struct nvhdr * nvh ; unsigned char * data , * ptr ; size_t dsize , size , vsize ; int error ; if ( nv == NULL ) { errno = ENOMEM ; return ( -1 ) ; } NV_CHECK ( nv ) ; PJDLOG_ASSERT ( nv -> nv_error == 0 ) ; error = 0 ; ptr = ebuf_data ( nv -> nv_ebuf , & size ) ; while ( size > 0 ) { if ( ptr [ 0 ] == ' \0 ' ) break ; if ( size < sizeof ( * nvh ) + 2 ) { error = EINVAL ; break ; } nvh = ( struct nvhdr * ) ptr ; if ( size < NVH_HSIZE ( nvh ) ) { error = EINVAL ; break ; } if ( nvh -> nvh_name [ nvh -> nvh_namesize - 1 ] != ' \0 ' ) { error = EINVAL ; break ; } if ( strlen ( nvh -> nvh_name ) != ( size_t ) ( nvh -> nvh_namesize - 1 ) ) { error = EINVAL ; break ; } if ( ( nvh -> nvh_type & NV_TYPE_MASK ) < NV_TYPE_FIRST || ( nvh -> nvh_type & NV_TYPE_MASK ) > NV_TYPE_LAST ) { error = EINVAL ; break ; } dsize = NVH_DSIZE ( nvh ) ; if ( dsize == 0 ) { error = EINVAL ; break ; } if ( size < NVH_SIZE ( nvh ) ) { error = EINVAL ; break ; } vsize = 0 ; switch ( nvh -> nvh_type & NV_TYPE_MASK ) { case NV_TYPE_INT8 : case NV_TYPE_UINT8 : if ( vsize == 0 ) vsize = 1 ; case NV_TYPE_INT16 : case NV_TYPE_UINT16 : if ( vsize == 0 ) vsize = 2 ; case NV_TYPE_INT32 : case NV_TYPE_UINT32 : if ( vsize == 0 ) vsize = 4 ; case NV_TYPE_INT64 : case NV_TYPE_UINT64 : if ( vsize == 0 ) vsize = 8 ; if ( dsize != vsize ) { error = EINVAL ; break ; } break ; case NV_TYPE_INT8_ARRAY : case NV_TYPE_UINT8_ARRAY : break ; case NV_TYPE_INT16_ARRAY : case NV_TYPE_UINT16_ARRAY : if ( vsize == 0 ) vsize = 2 ; case NV_TYPE_INT32_ARRAY : case NV_TYPE_UINT32_ARRAY : if ( vsize == 0 ) vsize = 4 ; case NV_TYPE_INT64_ARRAY : case NV_TYPE_UINT64_ARRAY : if ( vsize == 0 ) vsize = 8 ; if ( ( dsize % vsize ) != 0 ) { error = EINVAL ; break ; } break ; case NV_TYPE_STRING : data = NVH_DATA ( nvh ) ; if ( data [ dsize - 1 ] != ' \0 ' ) { error = EINVAL ; break ; } if ( strlen ( ( char * ) data ) != dsize - 1 ) { error = EINVAL ; break ; } break ; default : PJDLOG_ABORT ( " " ) ; } if ( error != 0 ) break ; ptr += NVH_SIZE ( nvh ) ; size -= NVH_SIZE ( nvh ) ; } if ( error != 0 ) { errno = error ; if ( nv -> nv_error == 0 ) nv -> nv_error = error ; return ( -1 ) ; } if ( extrap != NULL ) * extrap = size ; return ( 0 ) ; }
Validate correctness of the entire nv structure and all its elements.
Validate correctness of the entire nv structure and all its elements .
/* TODO: Check that names are unique? */ /*
		 * Zeros at the end of the buffer are acceptable.
		 */ /*
		 * Minimum size at this point is size of nvhdr structure, one
		 * character long name plus terminating '\0'.
		 */ /* FALLTHROUGH */ /* FALLTHROUGH */ /* FALLTHROUGH */ /* FALLTHROUGH */ /* FALLTHROUGH */