Initial commit
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
323
casadm/safeclib/strtok_s.c
Normal file
323
casadm/safeclib/strtok_s.c
Normal file
@@ -0,0 +1,323 @@
|
||||
/*------------------------------------------------------------------
|
||||
* strtok_s.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 by Cisco Systems, Inc
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "safeclib_private.h"
|
||||
#include "safe_str_constraint.h"
|
||||
#include "safe_str_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* strtok_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* char *
|
||||
* strtok_s(char *dest, rsize_t *dmax, char *src, char **ptr)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* A sequence of calls to the strtok_s function breaks the string
|
||||
* pointed to by dest into a sequence of tokens, each of which is
|
||||
* delimited by a character from the string pointed to by src. The
|
||||
* fourth argument points to a caller-provided char pointer into
|
||||
* which the strtok_s function stores information necessary for
|
||||
* it to continue scanning the same string.
|
||||
*
|
||||
* The first call in a sequence has a non-null first argument and
|
||||
* dmax points to an object whose value is the number of elements
|
||||
* in the character array pointed to by the first argument. The
|
||||
* first call stores an initial value in the object pointed to by
|
||||
* ptr and updates the value pointed to by dmax to reflect the
|
||||
* number of elements that remain in relation to ptr. Subsequent
|
||||
* calls in the sequence have a null first argument and the objects
|
||||
* pointed to by dmax and ptr are required to have the values
|
||||
* stored by the previous call in the sequence, which are then
|
||||
* updated. The separator string pointed to by src may be different
|
||||
* from call to call.
|
||||
*
|
||||
* The first call in the sequence searches the string pointed to
|
||||
* by dest for the first character that is not contained in the
|
||||
* current separator string pointed to by src. If no such character
|
||||
* is found, then there are no tokens in the string pointed to
|
||||
* by dest and the strtok_s function returns a null pointer. If
|
||||
* such a character is found, it is the start of the first token.
|
||||
*
|
||||
* The strtok_s function then searches from there for the first
|
||||
* character in dest that is contained in the current separator
|
||||
* string. If no such character is found, the current token
|
||||
* extends to the end of the string pointed to by dest, and
|
||||
* subsequent searches in the same string for a token return
|
||||
* a null pointer. If such a character is found, it is
|
||||
* overwritten by a null character, which terminates the
|
||||
* current token.
|
||||
*
|
||||
* In all cases, the strtok_s function stores sufficient information
|
||||
* in the pointer pointed to by ptr so that subsequent calls,
|
||||
* with a null pointer for dest and the unmodified pointer value
|
||||
* for ptr, shall start searching just past the element overwritten
|
||||
* by a null character (if any).
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC TR 24731-1, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string to tokenize
|
||||
*
|
||||
* dmax restricted maximum length of dest string
|
||||
*
|
||||
* src pointer to delimiter string (len < 255)
|
||||
*
|
||||
* ptr returned pointer to token
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dmax update length
|
||||
*
|
||||
* ptr update pointer to token
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* src shall not be a null pointer.
|
||||
* ptr shall not be a null pointer.
|
||||
* dmax shall not be a null pointer.
|
||||
* *dmax shall not be 0.
|
||||
*
|
||||
* If dest is a null pointer, then *ptr shall not be a null pointer.
|
||||
*
|
||||
* dest must not be unterminated.
|
||||
*
|
||||
* The value of *dmax shall not be greater than RSIZE_MAX_STR. The
|
||||
* end of the token found shall occur within the first *dmax
|
||||
* characters of dest for the first call, and shall occur within
|
||||
* the first *dmax characters of where searching resumes on
|
||||
* subsequent calls.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* The strtok_s function returns a pointer to the first character
|
||||
* of a token; or a null pointer if there is no token or there
|
||||
* is a runtime-constraint violation.
|
||||
*
|
||||
* EOK
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESUNTERM unterminated string
|
||||
*
|
||||
* EXAMPLES
|
||||
* [1] Sequencial strtok_s() calls to tokenize a string
|
||||
*
|
||||
* String to tokenize str1 = ",.:*one,two;three,;four*.*.five-six***"
|
||||
* len=38
|
||||
* String of delimiters str2 = ",.;*"
|
||||
*
|
||||
* p2tok = strtok_s(str1, &len, str2, &p2str);
|
||||
* token -one- remaining -two;three,;four*.*.five-six***- len=30
|
||||
*
|
||||
* p2tok = strtok_s(NULL, &len, str2, &p2str);
|
||||
* token -two- remaining -three,;four*.*.five-six***- len=26
|
||||
*
|
||||
* p2tok = strtok_s(NULL, &len, str2, &p2str);
|
||||
* token -three- remaining -;four*.*.five-six***- len=20
|
||||
*
|
||||
* p2tok = strtok_s(NULL, &len, str2, &p2str);
|
||||
* token -four- remaining -.*.five-six***- len=14
|
||||
*
|
||||
* p2tok = strtok_s(NULL, &len, str2, &p2str);
|
||||
* token -five-six- remaining -**- len=2
|
||||
*
|
||||
* p2tok = strtok_s(NULL, &len, str2, &p2str);
|
||||
* token -(null)- remaining -**- len=0
|
||||
*
|
||||
*
|
||||
* [2] While loop with same entry data as [1]
|
||||
*
|
||||
* p2tok = str1;
|
||||
* while (p2tok && len) {
|
||||
* p2tok = strtok_s(NULL, &len, str2, &p2str);
|
||||
* printf(" token -- remaining -- len=0 \n",
|
||||
* p2tok, p2str, (int)len );
|
||||
* }
|
||||
*
|
||||
*-
|
||||
*/
|
||||
char *
|
||||
strtok_s(char *dest, rsize_t *dmax, const char *src, char **ptr)
|
||||
{
|
||||
|
||||
/*
|
||||
* CONFIGURE: The spec does not call out a maximum for the src
|
||||
* string, so one is defined here.
|
||||
*/
|
||||
#define STRTOK_DELIM_MAX_LEN ( 16 )
|
||||
|
||||
|
||||
const char *pt;
|
||||
char *ptoken;
|
||||
rsize_t dlen;
|
||||
rsize_t slen;
|
||||
|
||||
if (dmax == NULL) {
|
||||
invoke_safe_str_constraint_handler("strtok_s: dmax is NULL",
|
||||
NULL, ESNULLP);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (*dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strtok_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (*dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strtok_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("strtok_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (ptr == NULL) {
|
||||
invoke_safe_str_constraint_handler("strtok_s: ptr is null",
|
||||
NULL, ESNULLP);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* if the source was NULL, use the tokenizer context */
|
||||
if (dest == NULL) {
|
||||
dest = *ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* scan dest for a delimiter
|
||||
*/
|
||||
dlen = *dmax;
|
||||
ptoken = NULL;
|
||||
while (*dest != '\0' && !ptoken) {
|
||||
|
||||
if (dlen == 0) {
|
||||
*ptr = NULL;
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strtok_s: dest is unterminated",
|
||||
NULL, ESUNTERM);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* must scan the entire delimiter list
|
||||
* ISO should have included a delimiter string limit!!
|
||||
*/
|
||||
slen = STRTOK_DELIM_MAX_LEN;
|
||||
pt = src;
|
||||
while (*pt != '\0') {
|
||||
|
||||
if (slen == 0) {
|
||||
*ptr = NULL;
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strtok_s: src is unterminated",
|
||||
NULL, ESUNTERM);
|
||||
return (NULL);
|
||||
}
|
||||
slen--;
|
||||
|
||||
if (*dest == *pt) {
|
||||
ptoken = NULL;
|
||||
break;
|
||||
} else {
|
||||
pt++;
|
||||
ptoken = dest;
|
||||
}
|
||||
}
|
||||
dest++;
|
||||
dlen--;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the beginning of a token was not found, then no
|
||||
* need to continue the scan.
|
||||
*/
|
||||
if (ptoken == NULL) {
|
||||
*dmax = dlen;
|
||||
return (ptoken);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we need to locate the end of the token
|
||||
*/
|
||||
while (*dest != '\0') {
|
||||
|
||||
if (dlen == 0) {
|
||||
*ptr = NULL;
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strtok_s: dest is unterminated",
|
||||
NULL, ESUNTERM);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
slen = STRTOK_DELIM_MAX_LEN;
|
||||
pt = src;
|
||||
while (*pt != '\0') {
|
||||
|
||||
if (slen == 0) {
|
||||
*ptr = NULL;
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strtok_s: src is unterminated",
|
||||
NULL, ESUNTERM);
|
||||
return (NULL);
|
||||
}
|
||||
slen--;
|
||||
|
||||
if (*dest == *pt) {
|
||||
/*
|
||||
* found a delimiter, set to null
|
||||
* and return context ptr to next char
|
||||
*/
|
||||
*dest = '\0';
|
||||
*ptr = (dest + 1); /* return pointer for next scan */
|
||||
*dmax = dlen - 1; /* account for the nulled delimiter */
|
||||
return (ptoken);
|
||||
} else {
|
||||
/*
|
||||
* simply scanning through the delimiter string
|
||||
*/
|
||||
pt++;
|
||||
}
|
||||
}
|
||||
dest++;
|
||||
dlen--;
|
||||
}
|
||||
|
||||
*dmax = dlen;
|
||||
return (ptoken);
|
||||
}
|
Reference in New Issue
Block a user