mirror of https://github.com/citusdata/citus.git
Merge pull request #3465 from citusdata/safestringlib
Use safestringlib for safe buffer interactionpull/3539/head
commit
5d601bb45a
|
@ -40,6 +40,9 @@ jobs:
|
|||
- run:
|
||||
name: 'Check if changed'
|
||||
command: git diff --exit-code
|
||||
- run:
|
||||
name: 'Check for banned C API usage'
|
||||
command: ci/banned.h.sh
|
||||
check-sql-snapshots:
|
||||
docker:
|
||||
- image: 'citus/extbuilder:latest'
|
||||
|
|
|
@ -26,10 +26,12 @@ configure -whitespace
|
|||
|
||||
# except these exceptions...
|
||||
src/backend/distributed/utils/citus_outfuncs.c -citus-style
|
||||
src/backend/distributed/utils/pg11_snprintf.c -citus-style
|
||||
src/backend/distributed/deparser/ruleutils_10.c -citus-style
|
||||
src/backend/distributed/deparser/ruleutils_11.c -citus-style
|
||||
src/backend/distributed/deparser/ruleutils_12.c -citus-style
|
||||
src/include/distributed/citus_nodes.h -citus-style
|
||||
/vendor/** -citus-style
|
||||
|
||||
# Hide diff on github by default for copied udfs
|
||||
src/backend/distributed/sql/udfs/*/[123456789]*.sql linguist-generated=true
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Checks for the APIs that are banned by microsoft. Since we compile for Linux
|
||||
# we use the replacements from https://github.com/intel/safestringlib
|
||||
# Not all replacement functions are available in safestringlib. If it doesn't
|
||||
# exist and you cannot rewrite the code to not use the banned API, then you can
|
||||
# add a comment containing "IGNORE-BANNED" to the line where the error is and
|
||||
# this check will ignore that match.
|
||||
#
|
||||
# The replacement function that you should use are listed here:
|
||||
# https://liquid.microsoft.com/Web/Object/Read/ms.security/Requirements/Microsoft.Security.SystemsADM.10082#guide
|
||||
|
||||
set -eu
|
||||
|
||||
files=$(find src -iname '*.[ch]' | git check-attr --stdin citus-style | grep -v ': unset$' | sed 's/: citus-style: set$//')
|
||||
|
||||
# grep is allowed to fail, that means no banned matches are found
|
||||
set +e
|
||||
# Required banned from banned.h. These functions are not allowed to be used at
|
||||
# all.
|
||||
# shellcheck disable=SC2086
|
||||
grep -E '\b(strcpy|strcpyA|strcpyW|wcscpy|_tcscpy|_mbscpy|StrCpy|StrCpyA|StrCpyW|lstrcpy|lstrcpyA|lstrcpyW|_tccpy|_mbccpy|_ftcscpy|strcat|strcatA|strcatW|wcscat|_tcscat|_mbscat|StrCat|StrCatA|StrCatW|lstrcat|lstrcatA|lstrcatW|StrCatBuff|StrCatBuffA|StrCatBuffW|StrCatChainW|_tccat|_mbccat|_ftcscat|sprintfW|sprintfA|wsprintf|wsprintfW|wsprintfA|sprintf|swprintf|_stprintf|wvsprintf|wvsprintfA|wvsprintfW|vsprintf|_vstprintf|vswprintf|strncpy|wcsncpy|_tcsncpy|_mbsncpy|_mbsnbcpy|StrCpyN|StrCpyNA|StrCpyNW|StrNCpy|strcpynA|StrNCpyA|StrNCpyW|lstrcpyn|lstrcpynA|lstrcpynW|strncat|wcsncat|_tcsncat|_mbsncat|_mbsnbcat|StrCatN|StrCatNA|StrCatNW|StrNCat|StrNCatA|StrNCatW|lstrncat|lstrcatnA|lstrcatnW|lstrcatn|gets|_getts|_gettws|IsBadWritePtr|IsBadHugeWritePtr|IsBadReadPtr|IsBadHugeReadPtr|IsBadCodePtr|IsBadStringPtr|memcpy|RtlCopyMemory|CopyMemory|wmemcpy|lstrlen)\(' $files \
|
||||
| grep -v "IGNORE-BANNED" \
|
||||
&& echo "ERROR: Required banned API usage detected" && exit 1
|
||||
|
||||
# Required banned from table on liquid. These functions are not allowed to be
|
||||
# used at all.
|
||||
# shellcheck disable=SC2086
|
||||
grep -E '\b(strcat|strcpy|strerror|strncat|strncpy|strtok|wcscat|wcscpy|wcsncat|wcsncpy|wcstok|fprintf|fwprintf|printf|snprintf|sprintf|swprintf|vfprintf|vprintf|vsnprintf|vsprintf|vswprintf|vwprintf|wprintf|fscanf|fwscanf|gets|scanf|sscanf|swscanf|vfscanf|vfwscanf|vscanf|vsscanf|vswscanf|vwscanf|wscanf|asctime|atof|atoi|atol|atoll|bsearch|ctime|fopen|freopen|getenv|gmtime|localtime|mbsrtowcs|mbstowcs|memcpy|memmove|qsort|rewind|setbuf|wmemcpy|wmemmove)\(' $files \
|
||||
| grep -v "IGNORE-BANNED" \
|
||||
&& echo "ERROR: Required banned API usage from table detected" && exit 1
|
||||
|
||||
# Recommended banned from banned.h. If you can change the code not to use these
|
||||
# that would be great. You can use IGNORE-BANNED if you need to use it anyway.
|
||||
# You can also remove it from the regex, if you want to mark the API as allowed
|
||||
# throughout the codebase (to not have to add IGNORED-BANNED everywhere). In
|
||||
# that case note it in this comment that you did so.
|
||||
# shellcheck disable=SC2086
|
||||
grep -E '\b(wnsprintf|wnsprintfA|wnsprintfW|_snwprintf|_snprintf|_sntprintf|_vsnprintf|vsnprintf|_vsnwprintf|_vsntprintf|wvnsprintf|wvnsprintfA|wvnsprintfW|strtok|_tcstok|wcstok|_mbstok|makepath|_tmakepath| _makepath|_wmakepath|_splitpath|_tsplitpath|_wsplitpath|scanf|wscanf|_tscanf|sscanf|swscanf|_stscanf|snscanf|snwscanf|_sntscanf|_itoa|_itow|_i64toa|_i64tow|_ui64toa|_ui64tot|_ui64tow|_ultoa|_ultot|_ultow|CharToOem|CharToOemA|CharToOemW|OemToChar|OemToCharA|OemToCharW|CharToOemBuffA|CharToOemBuffW|alloca|_alloca|ChangeWindowMessageFilter)\(' $files \
|
||||
| grep -v "IGNORE-BANNED" \
|
||||
&& echo "ERROR: Recomended banned API usage detected" && exit 1
|
||||
|
||||
# Recommended banned from table on liquid. If you can change the code not to use these
|
||||
# that would be great. You can use IGNORE-BANNED if you need to use it anyway.
|
||||
# You can also remove it from the regex, if you want to mark the API as allowed
|
||||
# throughout the codebase (to not have to add IGNORED-BANNED everywhere). In
|
||||
# that case note it in this comment that you did so.
|
||||
# Banned APIs ignored throughout the codebase:
|
||||
# - strlen
|
||||
# shellcheck disable=SC2086
|
||||
grep -E '\b(alloca|getwd|mktemp|tmpnam|wcrtomb|wcrtombs|wcslen|wcsrtombs|wcstombs|wctomb|class_addMethod|class_replaceMethod)\(' $files \
|
||||
| grep -v "IGNORE-BANNED" \
|
||||
&& echo "ERROR: Recomended banned API usage detected" && exit 1
|
||||
exit 0
|
|
@ -4,6 +4,7 @@ for f in $(git ls-tree -r HEAD --name-only); do
|
|||
if [ "$f" = "${f%.out}" ] &&
|
||||
[ "$f" = "${f%.data}" ] &&
|
||||
[ "$f" = "${f%.png}" ] &&
|
||||
[ "$(echo "$f" | cut -d / -f1)" != "vendor" ] &&
|
||||
[ "$(dirname "$f")" != "src/test/regress/output" ]
|
||||
then
|
||||
# Trim trailing whitespace
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
citus_subdir = src/backend/distributed
|
||||
citus_top_builddir = ../../..
|
||||
safestringlib_srcdir = $(citus_abs_top_srcdir)/vendor/safestringlib
|
||||
safestringlib_builddir = $(citus_top_builddir)/vendor/safestringlib/build
|
||||
safestringlib_a = $(safestringlib_builddir)/libsafestring_static.a
|
||||
safestringlib_sources = $(wildcard $(safestringlib_srcdir)/safeclib/*)
|
||||
|
||||
MODULE_big = citus
|
||||
EXTENSION = citus
|
||||
|
@ -39,11 +43,19 @@ utils/citus_version.o: $(CITUS_VERSION_INVALIDATE)
|
|||
|
||||
SHLIB_LINK += $(filter -lssl -lcrypto -lssleay32 -leay32, $(LIBS))
|
||||
|
||||
override CPPFLAGS += -I$(libpq_srcdir)
|
||||
override LDFLAGS += $(safestringlib_a)
|
||||
override CPPFLAGS += -I$(libpq_srcdir) -I$(safestringlib_srcdir)/include
|
||||
|
||||
SQL_DEPDIR=.deps/sql
|
||||
SQL_BUILDDIR=build/sql
|
||||
|
||||
$(safestringlib_a): $(safestringlib_sources)
|
||||
rm -rf $(safestringlib_builddir)
|
||||
mkdir -p $(safestringlib_builddir)
|
||||
cd $(safestringlib_builddir) && cmake $(safestringlib_srcdir) && make -j5
|
||||
|
||||
citus.so: $(safestringlib_a)
|
||||
|
||||
$(generated_sql_files): $(citus_abs_srcdir)/build/%: %
|
||||
@mkdir -p $(citus_abs_srcdir)/$(SQL_DEPDIR) $(citus_abs_srcdir)/$(SQL_BUILDDIR)
|
||||
cd $(citus_abs_srcdir) && cpp -undef -w -P -MMD -MP -MF$(SQL_DEPDIR)/$(*F).Po -MT$@ $< > $@
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "access/htup_details.h"
|
||||
#include "access/xact.h"
|
||||
#include "catalog/pg_collation.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/commands/utility_hook.h"
|
||||
#include "distributed/commands.h"
|
||||
#include "distributed/deparser.h"
|
||||
|
@ -529,16 +530,17 @@ GenerateBackupNameForCollationCollision(const ObjectAddress *address)
|
|||
|
||||
while (true)
|
||||
{
|
||||
int suffixLength = snprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)",
|
||||
count);
|
||||
int suffixLength = SafeSnprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)",
|
||||
count);
|
||||
|
||||
/* trim the base name at the end to leave space for the suffix and trailing \0 */
|
||||
baseLength = Min(baseLength, NAMEDATALEN - suffixLength - 1);
|
||||
|
||||
/* clear newName before copying the potentially trimmed baseName and suffix */
|
||||
memset(newName, 0, NAMEDATALEN);
|
||||
strncpy(newName, baseName, baseLength);
|
||||
strncpy(newName + baseLength, suffix, suffixLength);
|
||||
strncpy_s(newName, NAMEDATALEN, baseName, baseLength);
|
||||
strncpy_s(newName + baseLength, NAMEDATALEN - baseLength, suffix,
|
||||
suffixLength);
|
||||
|
||||
List *newCollationName = list_make2(namespace, makeString(newName));
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "catalog/pg_type.h"
|
||||
#include "commands/extension.h"
|
||||
#include "distributed/citus_ruleutils.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/colocation_utils.h"
|
||||
#include "distributed/commands.h"
|
||||
#include "distributed/commands/utility_hook.h"
|
||||
|
@ -1715,16 +1716,17 @@ GenerateBackupNameForProcCollision(const ObjectAddress *address)
|
|||
|
||||
while (true)
|
||||
{
|
||||
int suffixLength = snprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)",
|
||||
count);
|
||||
int suffixLength = SafeSnprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)",
|
||||
count);
|
||||
|
||||
/* trim the base name at the end to leave space for the suffix and trailing \0 */
|
||||
baseLength = Min(baseLength, NAMEDATALEN - suffixLength - 1);
|
||||
|
||||
/* clear newName before copying the potentially trimmed baseName and suffix */
|
||||
memset(newName, 0, NAMEDATALEN);
|
||||
strncpy(newName, baseName, baseLength);
|
||||
strncpy(newName + baseLength, suffix, suffixLength);
|
||||
strncpy_s(newName, NAMEDATALEN, baseName, baseLength);
|
||||
strncpy_s(newName + baseLength, NAMEDATALEN - baseLength, suffix,
|
||||
suffixLength);
|
||||
|
||||
List *newProcName = list_make2(namespace, makeString(newName));
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include "catalog/pg_type.h"
|
||||
#include "commands/copy.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/commands/multi_copy.h"
|
||||
#include "distributed/commands/utility_hook.h"
|
||||
#include "distributed/intermediate_results.h"
|
||||
|
@ -432,9 +433,8 @@ CopyToExistingShards(CopyStmt *copyStatement, char *completionTag)
|
|||
* There is no need to deep copy everything. We will just deep copy of the fields
|
||||
* we will change.
|
||||
*/
|
||||
memcpy(copiedDistributedRelation, distributedRelation, sizeof(RelationData));
|
||||
memcpy(copiedDistributedRelationTuple, distributedRelation->rd_rel,
|
||||
CLASS_TUPLE_SIZE);
|
||||
*copiedDistributedRelation = *distributedRelation;
|
||||
*copiedDistributedRelationTuple = *distributedRelation->rd_rel;
|
||||
|
||||
copiedDistributedRelation->rd_rel = copiedDistributedRelationTuple;
|
||||
copiedDistributedRelation->rd_att = CreateTupleDescCopyConstr(tupleDescriptor);
|
||||
|
@ -511,8 +511,8 @@ CopyToExistingShards(CopyStmt *copyStatement, char *completionTag)
|
|||
|
||||
if (completionTag != NULL)
|
||||
{
|
||||
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
|
||||
"COPY " UINT64_FORMAT, processedRowCount);
|
||||
SafeSnprintf(completionTag, COMPLETION_TAG_BUFSIZE,
|
||||
"COPY " UINT64_FORMAT, processedRowCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -696,8 +696,8 @@ CopyToNewShards(CopyStmt *copyStatement, char *completionTag, Oid relationId)
|
|||
|
||||
if (completionTag != NULL)
|
||||
{
|
||||
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
|
||||
"COPY " UINT64_FORMAT, processedRowCount);
|
||||
SafeSnprintf(completionTag, COMPLETION_TAG_BUFSIZE,
|
||||
"COPY " UINT64_FORMAT, processedRowCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2693,8 +2693,8 @@ ProcessCopyStmt(CopyStmt *copyStatement, char *completionTag, const char *queryS
|
|||
|
||||
int64 tuplesSent = WorkerExecuteSqlTask(query, filename, binaryCopyFormat);
|
||||
|
||||
snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
|
||||
"COPY " UINT64_FORMAT, tuplesSent);
|
||||
SafeSnprintf(completionTag, COMPLETION_TAG_BUFSIZE,
|
||||
"COPY " UINT64_FORMAT, tuplesSent);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2795,8 +2795,8 @@ CitusCopyTo(CopyStmt *copyStatement, char *completionTag)
|
|||
|
||||
if (completionTag != NULL)
|
||||
{
|
||||
snprintf(completionTag, COMPLETION_TAG_BUFSIZE, "COPY " UINT64_FORMAT,
|
||||
tuplesSent);
|
||||
SafeSnprintf(completionTag, COMPLETION_TAG_BUFSIZE, "COPY " UINT64_FORMAT,
|
||||
tuplesSent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "catalog/pg_enum.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/extension.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/commands.h"
|
||||
#include "distributed/commands/utility_hook.h"
|
||||
#include "distributed/deparser.h"
|
||||
|
@ -1075,16 +1076,17 @@ GenerateBackupNameForTypeCollision(const ObjectAddress *address)
|
|||
|
||||
while (true)
|
||||
{
|
||||
int suffixLength = snprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)",
|
||||
count);
|
||||
int suffixLength = SafeSnprintf(suffix, NAMEDATALEN - 1, "(citus_backup_%d)",
|
||||
count);
|
||||
|
||||
/* trim the base name at the end to leave space for the suffix and trailing \0 */
|
||||
baseLength = Min(baseLength, NAMEDATALEN - suffixLength - 1);
|
||||
|
||||
/* clear newName before copying the potentially trimmed baseName and suffix */
|
||||
memset(newName, 0, NAMEDATALEN);
|
||||
strncpy(newName, baseName, baseLength);
|
||||
strncpy(newName + baseLength, suffix, suffixLength);
|
||||
strncpy_s(newName, NAMEDATALEN, baseName, baseLength);
|
||||
strncpy_s(newName + baseLength, NAMEDATALEN - baseLength, suffix,
|
||||
suffixLength);
|
||||
|
||||
rel->relname = newName;
|
||||
TypeName *newTypeName = makeTypeNameFromNameList(MakeNameListFromRangeVar(rel));
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/connection_management.h"
|
||||
#include "distributed/metadata_cache.h"
|
||||
#include "distributed/worker_manager.h"
|
||||
|
@ -189,8 +190,8 @@ CheckConninfo(const char *conninfo, const char **whitelist,
|
|||
continue;
|
||||
}
|
||||
|
||||
void *matchingKeyword = bsearch(&option->keyword, whitelist, whitelistLength,
|
||||
sizeof(char *), pg_qsort_strcmp);
|
||||
void *matchingKeyword = SafeBsearch(&option->keyword, whitelist, whitelistLength,
|
||||
sizeof(char *), pg_qsort_strcmp);
|
||||
if (matchingKeyword == NULL)
|
||||
{
|
||||
/* the whitelist lacks this keyword; error out! */
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include "miscadmin.h"
|
||||
|
||||
#include "safe_lib.h"
|
||||
|
||||
#include "access/hash.h"
|
||||
#include "commands/dbcommands.h"
|
||||
#include "distributed/connection_management.h"
|
||||
|
@ -109,7 +111,8 @@ InitializeConnectionManagement(void)
|
|||
info.hcxt = ConnectionContext;
|
||||
uint32 hashFlags = (HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE);
|
||||
|
||||
memcpy(&connParamsInfo, &info, sizeof(HASHCTL));
|
||||
/* connParamsInfo is same as info, except for entrysize */
|
||||
connParamsInfo = info;
|
||||
connParamsInfo.entrysize = sizeof(ConnParamsHashEntry);
|
||||
|
||||
ConnectionHash = hash_create("citus connection cache (host,port,user,database)",
|
||||
|
@ -1223,7 +1226,8 @@ DefaultCitusNoticeProcessor(void *arg, const char *message)
|
|||
char *nodeName = connection->hostname;
|
||||
uint32 nodePort = connection->port;
|
||||
char *trimmedMessage = TrimLogLevel(message);
|
||||
char *level = strtok((char *) message, ":");
|
||||
char *strtokPosition;
|
||||
char *level = strtok_r((char *) message, ":", &strtokPosition);
|
||||
|
||||
ereport(CitusNoticeLogLevel,
|
||||
(errmsg("%s", ApplyLogRedaction(trimmedMessage)),
|
||||
|
|
|
@ -692,16 +692,17 @@ TrackerHash(const char *taskTrackerHashName, List *workerNodeList, char *userNam
|
|||
char *nodeName = workerNode->workerName;
|
||||
uint32 nodePort = workerNode->workerPort;
|
||||
|
||||
char taskStateHashName[MAXPGPATH];
|
||||
uint32 taskStateCount = 32;
|
||||
HASHCTL info;
|
||||
|
||||
/* insert task tracker into the tracker hash */
|
||||
TaskTracker *taskTracker = TrackerHashEnter(taskTrackerHash, nodeName, nodePort);
|
||||
|
||||
|
||||
/* for each task tracker, create hash to track its assigned tasks */
|
||||
snprintf(taskStateHashName, MAXPGPATH,
|
||||
"Task Tracker \"%s:%u\" Task State Hash", nodeName, nodePort);
|
||||
StringInfo taskStateHashName = makeStringInfo();
|
||||
appendStringInfo(taskStateHashName, "Task Tracker \"%s:%u\" Task State Hash",
|
||||
nodeName, nodePort);
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.keysize = sizeof(uint64) + sizeof(uint32);
|
||||
|
@ -710,12 +711,12 @@ TrackerHash(const char *taskTrackerHashName, List *workerNodeList, char *userNam
|
|||
info.hcxt = CurrentMemoryContext;
|
||||
int hashFlags = (HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
|
||||
|
||||
HTAB *taskStateHash = hash_create(taskStateHashName, taskStateCount, &info,
|
||||
HTAB *taskStateHash = hash_create(taskStateHashName->data, taskStateCount, &info,
|
||||
hashFlags);
|
||||
if (taskStateHash == NULL)
|
||||
{
|
||||
ereport(FATAL, (errcode(ERRCODE_OUT_OF_MEMORY),
|
||||
errmsg("could not initialize %s", taskStateHashName)));
|
||||
errmsg("could not initialize %s", taskStateHashName->data)));
|
||||
}
|
||||
|
||||
taskTracker->taskStateHash = taskStateHash;
|
||||
|
@ -781,7 +782,7 @@ TrackerHashEnter(HTAB *taskTrackerHash, char *nodeName, uint32 nodePort)
|
|||
}
|
||||
|
||||
/* init task tracker object with zeroed out task tracker key */
|
||||
memcpy(taskTracker, &taskTrackerKey, sizeof(TaskTracker));
|
||||
*taskTracker = taskTrackerKey;
|
||||
taskTracker->trackerStatus = TRACKER_CONNECT_START;
|
||||
taskTracker->connectionId = INVALID_CONNECTION_ID;
|
||||
taskTracker->currentTaskIndex = -1;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "distributed/colocation_utils.h"
|
||||
#include "distributed/connection_management.h"
|
||||
#include "distributed/citus_nodes.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/listutils.h"
|
||||
#include "distributed/master_metadata_utility.h"
|
||||
#include "distributed/master_protocol.h"
|
||||
|
@ -230,7 +231,7 @@ DistributedTableSizeOnWorker(WorkerNode *workerNode, Oid relationId, char *sizeQ
|
|||
List *sizeList = ReadFirstColumnAsText(result);
|
||||
StringInfo tableSizeStringInfo = (StringInfo) linitial(sizeList);
|
||||
char *tableSizeString = tableSizeStringInfo->data;
|
||||
uint64 tableSize = atol(tableSizeString);
|
||||
uint64 tableSize = SafeStringToUint64(tableSizeString);
|
||||
|
||||
PQclear(result);
|
||||
ClearResults(connection, raiseErrors);
|
||||
|
@ -608,7 +609,7 @@ void
|
|||
CopyShardPlacement(ShardPlacement *srcPlacement, ShardPlacement *destPlacement)
|
||||
{
|
||||
/* first copy all by-value fields */
|
||||
memcpy(destPlacement, srcPlacement, sizeof(ShardPlacement));
|
||||
*destPlacement = *srcPlacement;
|
||||
|
||||
/* and then the fields pointing to external values */
|
||||
if (srcPlacement->nodeName)
|
||||
|
|
|
@ -355,7 +355,7 @@ FilterActiveNodeListFunc(LOCKMODE lockMode, bool (*checkFunction)(WorkerNode *))
|
|||
if (workerNode->isActive && checkFunction(workerNode))
|
||||
{
|
||||
WorkerNode *workerNodeCopy = palloc0(sizeof(WorkerNode));
|
||||
memcpy(workerNodeCopy, workerNode, sizeof(WorkerNode));
|
||||
*workerNodeCopy = *workerNode;
|
||||
workerNodeList = lappend(workerNodeList, workerNodeCopy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -438,7 +438,7 @@ LoadGroupShardPlacement(uint64 shardId, uint64 placementId)
|
|||
{
|
||||
GroupShardPlacement *shardPlacement = CitusMakeNode(GroupShardPlacement);
|
||||
|
||||
memcpy(shardPlacement, &placementArray[i], sizeof(GroupShardPlacement));
|
||||
*shardPlacement = placementArray[i];
|
||||
|
||||
return shardPlacement;
|
||||
}
|
||||
|
@ -513,9 +513,11 @@ ResolveGroupShardPlacement(GroupShardPlacement *groupShardPlacement,
|
|||
WorkerNode *workerNode = LookupNodeForGroup(groupId);
|
||||
|
||||
/* copy everything into shardPlacement but preserve the header */
|
||||
memcpy((((CitusNode *) shardPlacement) + 1),
|
||||
(((CitusNode *) groupShardPlacement) + 1),
|
||||
sizeof(GroupShardPlacement) - sizeof(CitusNode));
|
||||
CitusNode header = shardPlacement->type;
|
||||
GroupShardPlacement *shardPlacementAsGroupPlacement =
|
||||
(GroupShardPlacement *) shardPlacement;
|
||||
*shardPlacementAsGroupPlacement = *groupShardPlacement;
|
||||
shardPlacement->type = header;
|
||||
|
||||
shardPlacement->nodeName = pstrdup(workerNode->workerName);
|
||||
shardPlacement->nodePort = workerNode->workerPort;
|
||||
|
@ -561,7 +563,7 @@ LookupNodeByNodeId(uint32 nodeId)
|
|||
if (workerNode->nodeId == nodeId)
|
||||
{
|
||||
WorkerNode *workerNodeCopy = palloc0(sizeof(WorkerNode));
|
||||
memcpy(workerNodeCopy, workerNode, sizeof(WorkerNode));
|
||||
*workerNodeCopy = *workerNode;
|
||||
|
||||
return workerNodeCopy;
|
||||
}
|
||||
|
@ -3597,7 +3599,7 @@ LookupDistPartitionTuple(Relation pgDistPartition, Oid relationId)
|
|||
ScanKeyData scanKey[1];
|
||||
|
||||
/* copy scankey to local copy, it will be modified during the scan */
|
||||
memcpy(scanKey, DistPartitionScanKey, sizeof(DistPartitionScanKey));
|
||||
scanKey[0] = DistPartitionScanKey[0];
|
||||
|
||||
/* set scan arguments */
|
||||
scanKey[0].sk_argument = ObjectIdGetDatum(relationId);
|
||||
|
@ -3631,7 +3633,7 @@ LookupDistShardTuples(Oid relationId)
|
|||
Relation pgDistShard = heap_open(DistShardRelationId(), AccessShareLock);
|
||||
|
||||
/* copy scankey to local copy, it will be modified during the scan */
|
||||
memcpy(scanKey, DistShardScanKey, sizeof(DistShardScanKey));
|
||||
scanKey[0] = DistShardScanKey[0];
|
||||
|
||||
/* set scan arguments */
|
||||
scanKey[0].sk_argument = ObjectIdGetDatum(relationId);
|
||||
|
|
|
@ -873,7 +873,7 @@ FindWorkerNode(char *nodeName, int32 nodePort)
|
|||
if (handleFound)
|
||||
{
|
||||
WorkerNode *workerNode = (WorkerNode *) palloc(sizeof(WorkerNode));
|
||||
memcpy(workerNode, cachedWorkerNode, sizeof(WorkerNode));
|
||||
*workerNode = *cachedWorkerNode;
|
||||
return workerNode;
|
||||
}
|
||||
|
||||
|
|
|
@ -1029,7 +1029,7 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
|
|||
standard_planner(newQuery, 0, boundParams);
|
||||
|
||||
/* overwrite the old transformed query with the new transformed query */
|
||||
memcpy(query, newQuery, sizeof(Query));
|
||||
*query = *newQuery;
|
||||
|
||||
/* recurse into CreateDistributedPlan with subqueries/CTEs replaced */
|
||||
distributedPlan = CreateDistributedPlan(planId, originalQuery, query, NULL, false,
|
||||
|
|
|
@ -3294,8 +3294,7 @@ CopyRelationRestrictionContext(RelationRestrictionContext *oldContext)
|
|||
|
||||
/* can't be copied, we copy (flatly) a RelOptInfo, and then decouple baserestrictinfo */
|
||||
newRestriction->relOptInfo = palloc(sizeof(RelOptInfo));
|
||||
memcpy(newRestriction->relOptInfo, oldRestriction->relOptInfo,
|
||||
sizeof(RelOptInfo));
|
||||
*newRestriction->relOptInfo = *oldRestriction->relOptInfo;
|
||||
|
||||
newRestriction->relOptInfo->baserestrictinfo =
|
||||
copyObject(oldRestriction->relOptInfo->baserestrictinfo);
|
||||
|
|
|
@ -1142,7 +1142,7 @@ RecursivelyPlanSubquery(Query *subquery, RecursivePlanningContext *planningConte
|
|||
}
|
||||
|
||||
/* finally update the input subquery to point the result query */
|
||||
memcpy(subquery, resultQuery, sizeof(Query));
|
||||
*subquery = *resultQuery;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -981,7 +981,7 @@ CopyPartialPruningInstance(PruningInstance *sourceInstance)
|
|||
* being partial - if necessary it'll be marked so again by
|
||||
* PrunableExpressionsWalker().
|
||||
*/
|
||||
memcpy(newInstance, sourceInstance, sizeof(PruningInstance));
|
||||
*newInstance = *sourceInstance;
|
||||
newInstance->addedToPruningInstances = false;
|
||||
newInstance->isPartial = false;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_class.h"
|
||||
#include "catalog/pg_constraint.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/commands.h"
|
||||
#include "distributed/metadata_cache.h"
|
||||
#include "distributed/relay_utility.h"
|
||||
|
@ -694,8 +695,8 @@ AppendShardIdToName(char **name, uint64 shardId)
|
|||
NAMEDATALEN)));
|
||||
}
|
||||
|
||||
snprintf(shardIdAndSeparator, NAMEDATALEN, "%c" UINT64_FORMAT,
|
||||
SHARD_NAME_SEPARATOR, shardId);
|
||||
SafeSnprintf(shardIdAndSeparator, NAMEDATALEN, "%c" UINT64_FORMAT,
|
||||
SHARD_NAME_SEPARATOR, shardId);
|
||||
int shardIdAndSeparatorLength = strlen(shardIdAndSeparator);
|
||||
|
||||
/*
|
||||
|
@ -705,7 +706,7 @@ AppendShardIdToName(char **name, uint64 shardId)
|
|||
|
||||
if (nameLength < (NAMEDATALEN - shardIdAndSeparatorLength))
|
||||
{
|
||||
snprintf(extendedName, NAMEDATALEN, "%s%s", (*name), shardIdAndSeparator);
|
||||
SafeSnprintf(extendedName, NAMEDATALEN, "%s%s", (*name), shardIdAndSeparator);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -739,14 +740,14 @@ AppendShardIdToName(char **name, uint64 shardId)
|
|||
multiByteClipLength = pg_mbcliplen(*name, nameLength, (NAMEDATALEN -
|
||||
shardIdAndSeparatorLength -
|
||||
10));
|
||||
snprintf(extendedName, NAMEDATALEN, "%.*s%c%.8x%s",
|
||||
multiByteClipLength, (*name),
|
||||
SHARD_NAME_SEPARATOR, longNameHash,
|
||||
shardIdAndSeparator);
|
||||
SafeSnprintf(extendedName, NAMEDATALEN, "%.*s%c%.8x%s",
|
||||
multiByteClipLength, (*name),
|
||||
SHARD_NAME_SEPARATOR, longNameHash,
|
||||
shardIdAndSeparator);
|
||||
}
|
||||
|
||||
(*name) = (char *) repalloc((*name), NAMEDATALEN);
|
||||
int neededBytes = snprintf((*name), NAMEDATALEN, "%s", extendedName);
|
||||
int neededBytes = SafeSnprintf((*name), NAMEDATALEN, "%s", extendedName);
|
||||
if (neededBytes < 0)
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY),
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* necessary to get alloca() on illumos */
|
||||
/* necessary to get alloca on illumos */
|
||||
#ifdef __sun
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
@ -21,11 +21,14 @@
|
|||
#include "fmgr.h"
|
||||
#include "miscadmin.h"
|
||||
|
||||
#include "safe_lib.h"
|
||||
|
||||
#include "citus_version.h"
|
||||
#include "commands/explain.h"
|
||||
#include "executor/executor.h"
|
||||
#include "distributed/backend_data.h"
|
||||
#include "distributed/citus_nodefuncs.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/commands.h"
|
||||
#include "distributed/commands/multi_copy.h"
|
||||
#include "distributed/commands/utility_hook.h"
|
||||
|
@ -187,6 +190,14 @@ _PG_init(void)
|
|||
"shared_preload_libraries.")));
|
||||
}
|
||||
|
||||
/*
|
||||
* Register contstraint_handler hooks of safestringlib first. This way
|
||||
* loading the extension will error out if one of these constraints are hit
|
||||
* during load.
|
||||
*/
|
||||
set_str_constraint_handler_s(ereport_constraint_handler);
|
||||
set_mem_constraint_handler_s(ereport_constraint_handler);
|
||||
|
||||
/*
|
||||
* Perform checks before registering any hooks, to avoid erroring out in a
|
||||
* partial state.
|
||||
|
@ -290,7 +301,13 @@ ResizeStackToMaximumDepth(void)
|
|||
#ifndef WIN32
|
||||
long max_stack_depth_bytes = max_stack_depth * 1024L;
|
||||
|
||||
volatile char *stack_resizer = alloca(max_stack_depth_bytes);
|
||||
/*
|
||||
* Explanation of IGNORE-BANNED:
|
||||
* alloca is safe to use here since we limit the allocated size. We cannot
|
||||
* use malloc as a replacement, since we actually want to grow the stack
|
||||
* here.
|
||||
*/
|
||||
volatile char *stack_resizer = alloca(max_stack_depth_bytes); /* IGNORE-BANNED */
|
||||
|
||||
/*
|
||||
* Different architectures might have different directions while
|
||||
|
|
|
@ -806,7 +806,7 @@ GetBackendDataForProc(PGPROC *proc, BackendData *result)
|
|||
|
||||
SpinLockAcquire(&backendData->mutex);
|
||||
|
||||
memcpy(result, backendData, sizeof(BackendData));
|
||||
*result = *backendData;
|
||||
|
||||
SpinLockRelease(&backendData->mutex);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "access/xact.h"
|
||||
#include "distributed/backend_data.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/connection_management.h"
|
||||
#include "distributed/metadata_cache.h"
|
||||
#include "distributed/remote_commands.h"
|
||||
|
@ -1330,9 +1331,9 @@ Assign2PCIdentifier(MultiConnection *connection)
|
|||
uint64 transactionNumber = CurrentDistributedTransactionNumber();
|
||||
|
||||
/* print all numbers as unsigned to guarantee no minus symbols appear in the name */
|
||||
snprintf(connection->remoteTransaction.preparedName, NAMEDATALEN,
|
||||
PREPARED_TRANSACTION_NAME_FORMAT, GetLocalGroupId(), MyProcPid,
|
||||
transactionNumber, connectionNumber++);
|
||||
SafeSnprintf(connection->remoteTransaction.preparedName, NAMEDATALEN,
|
||||
PREPARED_TRANSACTION_NAME_FORMAT, GetLocalGroupId(), MyProcPid,
|
||||
transactionNumber, connectionNumber++);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "access/twophase.h"
|
||||
#include "access/xact.h"
|
||||
#include "distributed/backend_data.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/connection_management.h"
|
||||
#include "distributed/distributed_planner.h"
|
||||
#include "distributed/hash_helpers.h"
|
||||
|
@ -538,7 +539,7 @@ AdjustMaxPreparedTransactions(void)
|
|||
{
|
||||
char newvalue[12];
|
||||
|
||||
snprintf(newvalue, sizeof(newvalue), "%d", MaxConnections * 2);
|
||||
SafeSnprintf(newvalue, sizeof(newvalue), "%d", MaxConnections * 2);
|
||||
|
||||
SetConfigOption("max_prepared_transactions", newvalue, PGC_POSTMASTER,
|
||||
PGC_S_OVERRIDE);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "utils/snapmgr.h"
|
||||
|
||||
#include "distributed/citus_acquire_lock.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/connection_management.h"
|
||||
#include "distributed/version_compat.h"
|
||||
|
||||
|
@ -75,27 +76,21 @@ StartLockAcquireHelperBackgroundWorker(int backendToHelp, int32 lock_cooldown)
|
|||
args.lock_cooldown = lock_cooldown;
|
||||
|
||||
/* construct the background worker and start it */
|
||||
snprintf(worker.bgw_name, BGW_MAXLEN,
|
||||
"Citus Lock Acquire Helper: %d/%u",
|
||||
backendToHelp, MyDatabaseId);
|
||||
snprintf(worker.bgw_type, BGW_MAXLEN, "citus_lock_aqcuire");
|
||||
SafeSnprintf(worker.bgw_name, sizeof(worker.bgw_name),
|
||||
"Citus Lock Acquire Helper: %d/%u", backendToHelp, MyDatabaseId);
|
||||
strcpy_s(worker.bgw_type, sizeof(worker.bgw_type), "citus_lock_aqcuire");
|
||||
|
||||
worker.bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION;
|
||||
worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
|
||||
worker.bgw_restart_time = BGW_NEVER_RESTART;
|
||||
|
||||
snprintf(worker.bgw_library_name, BGW_MAXLEN, "citus");
|
||||
snprintf(worker.bgw_function_name, BGW_MAXLEN, "LockAcquireHelperMain");
|
||||
strcpy_s(worker.bgw_library_name, sizeof(worker.bgw_library_name), "citus");
|
||||
strcpy_s(worker.bgw_function_name, sizeof(worker.bgw_function_name),
|
||||
"LockAcquireHelperMain");
|
||||
worker.bgw_main_arg = Int32GetDatum(backendToHelp);
|
||||
worker.bgw_notify_pid = 0;
|
||||
|
||||
/*
|
||||
* we check if args fits in bgw_extra to make sure it is safe to copy the data. Once
|
||||
* we exceed the size of data to copy this way we need to look into a different way of
|
||||
* passing the arguments to the worker.
|
||||
*/
|
||||
Assert(sizeof(worker.bgw_extra) >= sizeof(args));
|
||||
memcpy(worker.bgw_extra, &args, sizeof(args));
|
||||
memcpy_s(worker.bgw_extra, sizeof(worker.bgw_extra), &args, sizeof(args));
|
||||
|
||||
if (!RegisterDynamicBackgroundWorker(&worker, &handle))
|
||||
{
|
||||
|
|
|
@ -0,0 +1,309 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* safe_lib.c
|
||||
*
|
||||
* This file contains all SafeXXXX helper functions that we implement to
|
||||
* replace missing xxxx_s functions implemented by safestringlib. It also
|
||||
* contains a constraint handler for use in both our SafeXXX and safestringlib
|
||||
* its xxxx_s functions.
|
||||
*
|
||||
* Copyright (c) Citus Data, Inc.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "safe_lib.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "lib/stringinfo.h"
|
||||
|
||||
/*
|
||||
* In PG 11 pg_vsnprintf is not exported and compiled in most cases, in that
|
||||
* case use the copied one from pg11_snprintf.c
|
||||
* NOTE: Whenever removing this section also remove pg11_snprintf.c
|
||||
*/
|
||||
#if PG_VERSION_NUM < 120000
|
||||
extern int pg11_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
|
||||
#define citus_vsnprintf pg11_vsnprintf
|
||||
#else
|
||||
#define citus_vsnprintf pg_vsnprintf
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* ereport_constraint_handler is a constraint handler that calls ereport. A
|
||||
* constraint handler is called whenever an error occurs in any of the
|
||||
* safestringlib xxxx_s functions or our SafeXXXX functions.
|
||||
*
|
||||
* More info on constraint handlers can be found here:
|
||||
* https://en.cppreference.com/w/c/error/set_constraint_handler_s
|
||||
*/
|
||||
void
|
||||
ereport_constraint_handler(const char *message,
|
||||
void *pointer,
|
||||
errno_t error)
|
||||
{
|
||||
if (message && error)
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg(
|
||||
"Memory constraint error: %s (errno %d)", message, error)));
|
||||
}
|
||||
else if (message)
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg(
|
||||
"Memory constraint error: %s", message)));
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg(
|
||||
"Unknown function failed with memory constraint error (errno %d)",
|
||||
error)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg(
|
||||
"Unknown function failed with memory constraint error")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SafeStringToInt64 converts a string containing a number to a int64. When it
|
||||
* fails it calls ereport.
|
||||
*
|
||||
* The different error cases are inspired by
|
||||
* https://stackoverflow.com/a/26083517/2570866
|
||||
*/
|
||||
int64
|
||||
SafeStringToInt64(const char *str)
|
||||
{
|
||||
char *endptr;
|
||||
errno = 0;
|
||||
int64 number = strtol(str, &endptr, 10);
|
||||
|
||||
if (str == endptr)
|
||||
{
|
||||
ereport(ERROR, (errmsg("Error parsing %s as int64, no digits found\n", str)));
|
||||
}
|
||||
else if (errno == ERANGE && number == LONG_MIN)
|
||||
{
|
||||
ereport(ERROR, (errmsg("Error parsing %s as int64, underflow occured\n", str)));
|
||||
}
|
||||
else if (errno == ERANGE && number == LONG_MAX)
|
||||
{
|
||||
ereport(ERROR, (errmsg("Error parsing %s as int64, overflow occured\n", str)));
|
||||
}
|
||||
else if (errno == EINVAL)
|
||||
{
|
||||
ereport(ERROR, (errmsg(
|
||||
"Error parsing %s as int64, base contains unsupported value\n",
|
||||
str)));
|
||||
}
|
||||
else if (errno != 0 && number == 0)
|
||||
{
|
||||
int err = errno;
|
||||
ereport(ERROR, (errmsg("Error parsing %s as int64, errno %d\n", str, err)));
|
||||
}
|
||||
else if (errno == 0 && str && *endptr != '\0')
|
||||
{
|
||||
ereport(ERROR, (errmsg(
|
||||
"Error parsing %s as int64, aditional characters remain after int64\n",
|
||||
str)));
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SafeStringToUint64 converts a string containing a number to a uint64. When it
|
||||
* fails it calls ereport.
|
||||
*
|
||||
* The different error cases are inspired by
|
||||
* https://stackoverflow.com/a/26083517/2570866
|
||||
*/
|
||||
uint64
|
||||
SafeStringToUint64(const char *str)
|
||||
{
|
||||
char *endptr;
|
||||
errno = 0;
|
||||
uint64 number = strtoul(str, &endptr, 10);
|
||||
|
||||
if (str == endptr)
|
||||
{
|
||||
ereport(ERROR, (errmsg("Error parsing %s as uint64, no digits found\n", str)));
|
||||
}
|
||||
else if (errno == ERANGE && number == LONG_MIN)
|
||||
{
|
||||
ereport(ERROR, (errmsg("Error parsing %s as uint64, underflow occured\n", str)));
|
||||
}
|
||||
else if (errno == ERANGE && number == LONG_MAX)
|
||||
{
|
||||
ereport(ERROR, (errmsg("Error parsing %s as uint64, overflow occured\n", str)));
|
||||
}
|
||||
else if (errno == EINVAL)
|
||||
{
|
||||
ereport(ERROR, (errmsg(
|
||||
"Error parsing %s as uint64, base contains unsupported value\n",
|
||||
str)));
|
||||
}
|
||||
else if (errno != 0 && number == 0)
|
||||
{
|
||||
int err = errno;
|
||||
ereport(ERROR, (errmsg("Error parsing %s as uint64, errno %d\n", str, err)));
|
||||
}
|
||||
else if (errno == 0 && str && *endptr != '\0')
|
||||
{
|
||||
ereport(ERROR, (errmsg(
|
||||
"Error parsing %s as uint64, aditional characters remain after uint64\n",
|
||||
str)));
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SafeQsort is the non reentrant version of qsort (qsort vs qsort_r), but it
|
||||
* does the input checks required for qsort_s:
|
||||
* 1. count or size is greater than RSIZE_MAX
|
||||
* 2. ptr or comp is a null pointer (unless count is zero)
|
||||
* source: https://en.cppreference.com/w/c/algorithm/qsort
|
||||
*
|
||||
* When it hits these errors it calls the ereport_constraint_handler.
|
||||
*
|
||||
* NOTE: this functions calls pg_qsort instead of stdlib qsort.
|
||||
*/
|
||||
void
|
||||
SafeQsort(void *ptr, rsize_t count, rsize_t size,
|
||||
int (*comp)(const void *, const void *))
|
||||
{
|
||||
if (count > RSIZE_MAX_MEM)
|
||||
{
|
||||
ereport_constraint_handler("SafeQsort: count exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
}
|
||||
|
||||
if (size > RSIZE_MAX_MEM)
|
||||
{
|
||||
ereport_constraint_handler("SafeQsort: size exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
}
|
||||
if (size != 0)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
{
|
||||
ereport_constraint_handler("SafeQsort: ptr is NULL", NULL, ESNULLP);
|
||||
}
|
||||
if (comp == NULL)
|
||||
{
|
||||
ereport_constraint_handler("SafeQsort: comp is NULL", NULL, ESNULLP);
|
||||
}
|
||||
}
|
||||
pg_qsort(ptr, count, size, comp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SafeBsearch is a non reentrant version of bsearch, but it does the
|
||||
* input checks required for bsearch_s:
|
||||
* 1. count or size is greater than RSIZE_MAX
|
||||
* 2. key, ptr or comp is a null pointer (unless count is zero)
|
||||
* source: https://en.cppreference.com/w/c/algorithm/bsearch
|
||||
*
|
||||
* When it hits these errors it calls the ereport_constraint_handler.
|
||||
*
|
||||
* NOTE: this functions calls pg_qsort instead of stdlib qsort.
|
||||
*/
|
||||
void *
|
||||
SafeBsearch(const void *key, const void *ptr, rsize_t count, rsize_t size,
|
||||
int (*comp)(const void *, const void *))
|
||||
{
|
||||
if (count > RSIZE_MAX_MEM)
|
||||
{
|
||||
ereport_constraint_handler("SafeBsearch: count exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
}
|
||||
|
||||
if (size > RSIZE_MAX_MEM)
|
||||
{
|
||||
ereport_constraint_handler("SafeBsearch: size exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
}
|
||||
if (size != 0)
|
||||
{
|
||||
if (key == NULL)
|
||||
{
|
||||
ereport_constraint_handler("SafeBsearch: key is NULL", NULL, ESNULLP);
|
||||
}
|
||||
if (ptr == NULL)
|
||||
{
|
||||
ereport_constraint_handler("SafeBsearch: ptr is NULL", NULL, ESNULLP);
|
||||
}
|
||||
if (comp == NULL)
|
||||
{
|
||||
ereport_constraint_handler("SafeBsearch: comp is NULL", NULL, ESNULLP);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Explanation of IGNORE-BANNED:
|
||||
* bsearch is safe to use here since we check the same thing bsearch_s
|
||||
* does. We cannot use bsearch_s as a replacement, since it's not available
|
||||
* in safestringlib.
|
||||
*/
|
||||
return bsearch(key, ptr, count, size, comp); /* IGNORE-BANNED */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SafeSnprintf is a safer replacement for snprintf, which is needed since
|
||||
* safestringlib doesn't implement snprintf_s.
|
||||
*
|
||||
* The required failure modes of snprint_s are as follows (in parentheses if
|
||||
* this implements it and how):
|
||||
* 1. the conversion specifier %n is present in format (yes, %n is not
|
||||
* supported by pg_vsnprintf)
|
||||
* 2. any of the arguments corresponding to %s is a null pointer (half, checked
|
||||
* in postgres when asserts are enabled)
|
||||
* 3. format or buffer is a null pointer (yes, checked by this function)
|
||||
* 4. bufsz is zero or greater than RSIZE_MAX (yes, checked by this function)
|
||||
* 5. encoding errors occur in any of string and character conversion
|
||||
* specifiers (no clue what postgres does in this case)
|
||||
* source: https://en.cppreference.com/w/c/io/fprintf
|
||||
*/
|
||||
int
|
||||
SafeSnprintf(char *restrict buffer, rsize_t bufsz, const char *restrict format, ...)
|
||||
{
|
||||
/* failure mode 3 */
|
||||
if (buffer == NULL)
|
||||
{
|
||||
ereport_constraint_handler("SafeSnprintf: buffer is NULL", NULL, ESNULLP);
|
||||
}
|
||||
if (format == NULL)
|
||||
{
|
||||
ereport_constraint_handler("SafeSnprintf: format is NULL", NULL, ESNULLP);
|
||||
}
|
||||
|
||||
/* failure mode 4 */
|
||||
if (bufsz == 0)
|
||||
{
|
||||
ereport_constraint_handler("SafeSnprintf: bufsz is 0",
|
||||
NULL, ESZEROL);
|
||||
}
|
||||
|
||||
if (bufsz > RSIZE_MAX_STR)
|
||||
{
|
||||
ereport_constraint_handler("SafeSnprintf: bufsz exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
}
|
||||
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
size_t result = citus_vsnprintf(buffer, bufsz, format, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "utils/lsyscache.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/listutils.h"
|
||||
#include "nodes/pg_list.h"
|
||||
#include "utils/memutils.h"
|
||||
|
@ -49,7 +50,7 @@ SortList(List *pointerList, int (*comparisonFunction)(const void *, const void *
|
|||
}
|
||||
|
||||
/* sort the array of pointers using the comparison function */
|
||||
qsort(array, arraySize, sizeof(void *), comparisonFunction);
|
||||
SafeQsort(array, arraySize, sizeof(void *), comparisonFunction);
|
||||
|
||||
/* convert the sorted array of pointers back to a sorted list */
|
||||
for (arrayIndex = 0; arrayIndex < arraySize; arrayIndex++)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "commands/extension.h"
|
||||
#include "libpq/pqsignal.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/distributed_deadlock_detection.h"
|
||||
#include "distributed/maintenanced.h"
|
||||
#include "distributed/master_protocol.h"
|
||||
|
@ -171,9 +172,9 @@ InitializeMaintenanceDaemonBackend(void)
|
|||
|
||||
memset(&worker, 0, sizeof(worker));
|
||||
|
||||
snprintf(worker.bgw_name, BGW_MAXLEN,
|
||||
"Citus Maintenance Daemon: %u/%u",
|
||||
MyDatabaseId, extensionOwner);
|
||||
SafeSnprintf(worker.bgw_name, sizeof(worker.bgw_name),
|
||||
"Citus Maintenance Daemon: %u/%u",
|
||||
MyDatabaseId, extensionOwner);
|
||||
|
||||
/* request ability to connect to target database */
|
||||
worker.bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION;
|
||||
|
@ -186,10 +187,14 @@ InitializeMaintenanceDaemonBackend(void)
|
|||
|
||||
/* Restart after a bit after errors, but don't bog the system. */
|
||||
worker.bgw_restart_time = 5;
|
||||
sprintf(worker.bgw_library_name, "citus");
|
||||
sprintf(worker.bgw_function_name, "CitusMaintenanceDaemonMain");
|
||||
strcpy_s(worker.bgw_library_name,
|
||||
sizeof(worker.bgw_library_name), "citus");
|
||||
strcpy_s(worker.bgw_function_name, sizeof(worker.bgw_library_name),
|
||||
"CitusMaintenanceDaemonMain");
|
||||
|
||||
worker.bgw_main_arg = ObjectIdGetDatum(MyDatabaseId);
|
||||
memcpy(worker.bgw_extra, &extensionOwner, sizeof(Oid));
|
||||
memcpy_s(worker.bgw_extra, sizeof(worker.bgw_extra), &extensionOwner,
|
||||
sizeof(Oid));
|
||||
worker.bgw_notify_pid = MyProcPid;
|
||||
|
||||
if (!RegisterDynamicBackgroundWorker(&worker, &handle))
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,17 +21,7 @@ PG_FUNCTION_INFO_V1(citus_server_id);
|
|||
#ifdef HAVE_LIBCURL
|
||||
|
||||
#include <curl/curl.h>
|
||||
#ifndef WIN32
|
||||
#include <sys/utsname.h>
|
||||
#else
|
||||
typedef struct utsname
|
||||
{
|
||||
char sysname[65];
|
||||
char release[65];
|
||||
char version[65];
|
||||
char machine[65];
|
||||
} utsname;
|
||||
#endif
|
||||
|
||||
#include "access/xact.h"
|
||||
#include "distributed/metadata_cache.h"
|
||||
|
@ -54,9 +44,6 @@ static bool SendHttpPostJsonRequest(const char *url, const char *postFields,
|
|||
long timeoutSeconds,
|
||||
curl_write_callback responseCallback);
|
||||
static bool PerformHttpRequest(CURL *curl);
|
||||
#ifdef WIN32
|
||||
static int uname(struct utsname *buf);
|
||||
#endif
|
||||
|
||||
|
||||
/* WarnIfSyncDNS warns if libcurl is compiled with synchronous DNS. */
|
||||
|
@ -360,103 +347,3 @@ citus_server_id(PG_FUNCTION_ARGS)
|
|||
|
||||
PG_RETURN_UUID_P((pg_uuid_t *) buf);
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
/*
|
||||
* Inspired by perl5's win32_uname
|
||||
* https://github.com/Perl/perl5/blob/69374fe705978962b85217f3eb828a93f836fd8d/win32/win32.c#L2057
|
||||
*/
|
||||
static int
|
||||
uname(struct utsname *buf)
|
||||
{
|
||||
OSVERSIONINFO ver;
|
||||
|
||||
ver.dwOSVersionInfoSize = sizeof(ver);
|
||||
GetVersionEx(&ver);
|
||||
|
||||
switch (ver.dwPlatformId)
|
||||
{
|
||||
case VER_PLATFORM_WIN32_WINDOWS:
|
||||
{
|
||||
strcpy(buf->sysname, "Windows");
|
||||
break;
|
||||
}
|
||||
|
||||
case VER_PLATFORM_WIN32_NT:
|
||||
{
|
||||
strcpy(buf->sysname, "Windows NT");
|
||||
break;
|
||||
}
|
||||
|
||||
case VER_PLATFORM_WIN32s:
|
||||
{
|
||||
strcpy(buf->sysname, "Win32s");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
strcpy(buf->sysname, "Win32 Unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(buf->release, "%d.%d", ver.dwMajorVersion, ver.dwMinorVersion);
|
||||
|
||||
{
|
||||
SYSTEM_INFO info;
|
||||
char *arch;
|
||||
|
||||
GetSystemInfo(&info);
|
||||
DWORD procarch = info.wProcessorArchitecture;
|
||||
|
||||
switch (procarch)
|
||||
{
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
{
|
||||
arch = "x86";
|
||||
break;
|
||||
}
|
||||
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
{
|
||||
arch = "x86";
|
||||
break;
|
||||
}
|
||||
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
{
|
||||
arch = "x86";
|
||||
break;
|
||||
}
|
||||
|
||||
case PROCESSOR_ARCHITECTURE_UNKNOWN:
|
||||
{
|
||||
arch = "x86";
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
arch = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (arch != NULL)
|
||||
{
|
||||
strcpy(buf->machine, arch);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(buf->machine, "unknown(0x%x)", procarch);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "commands/dbcommands.h"
|
||||
#include "distributed/citus_safe_lib.h"
|
||||
#include "distributed/multi_client_executor.h"
|
||||
#include "distributed/multi_server_executor.h"
|
||||
#include "distributed/task_tracker.h"
|
||||
|
@ -117,10 +118,11 @@ TaskTrackerRegister(void)
|
|||
worker.bgw_flags = BGWORKER_SHMEM_ACCESS;
|
||||
worker.bgw_start_time = BgWorkerStart_ConsistentState;
|
||||
worker.bgw_restart_time = 1;
|
||||
snprintf(worker.bgw_library_name, BGW_MAXLEN, "citus");
|
||||
snprintf(worker.bgw_function_name, BGW_MAXLEN, "TaskTrackerMain");
|
||||
strcpy_s(worker.bgw_library_name, sizeof(worker.bgw_library_name), "citus");
|
||||
strcpy_s(worker.bgw_function_name, sizeof(worker.bgw_function_name),
|
||||
"TaskTrackerMain");
|
||||
worker.bgw_notify_pid = 0;
|
||||
snprintf(worker.bgw_name, BGW_MAXLEN, "task tracker");
|
||||
strcpy_s(worker.bgw_name, sizeof(worker.bgw_name), "task tracker");
|
||||
|
||||
RegisterBackgroundWorker(&worker);
|
||||
}
|
||||
|
@ -702,7 +704,7 @@ SchedulableTaskPriorityQueue(HTAB *WorkerTasksHash)
|
|||
}
|
||||
|
||||
/* now order elements in the queue according to our sorting criterion */
|
||||
qsort(priorityQueue, queueSize, WORKER_TASK_SIZE, CompareTasksByTime);
|
||||
SafeQsort(priorityQueue, queueSize, WORKER_TASK_SIZE, CompareTasksByTime);
|
||||
|
||||
return priorityQueue;
|
||||
}
|
||||
|
|
|
@ -226,7 +226,7 @@ ReceiveRegularFile(const char *nodeName, uint32 nodePort, const char *nodeUser,
|
|||
bool copyDone = false;
|
||||
|
||||
/* create local file to append remote data to */
|
||||
snprintf(filename, MAXPGPATH, "%s", filePath->data);
|
||||
strlcpy(filename, filePath->data, MAXPGPATH);
|
||||
|
||||
int32 fileDescriptor = BasicOpenFilePerm(filename, fileFlags, fileMode);
|
||||
if (fileDescriptor < 0)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* safe_lib.h
|
||||
*
|
||||
* This file contains helper functions to expand on the _s functions from
|
||||
* safestringlib.
|
||||
*
|
||||
* Copyright (c) Citus Data, Inc.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef CITUS_safe_lib_H
|
||||
#define CITUS_safe_lib_H
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "safe_lib.h"
|
||||
|
||||
extern void ereport_constraint_handler(const char *message, void *pointer, errno_t error);
|
||||
extern int64 SafeStringToInt64(const char *str);
|
||||
extern uint64 SafeStringToUint64(const char *str);
|
||||
extern void SafeQsort(void *ptr, rsize_t count, rsize_t size,
|
||||
int (*comp)(const void *, const void *));
|
||||
void * SafeBsearch(const void *key, const void *ptr, rsize_t count, rsize_t size,
|
||||
int (*comp)(const void *, const void *));
|
||||
int SafeSnprintf(char *str, rsize_t count, const char *fmt, ...);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
# Updating vendored dependencies
|
||||
|
||||
```bash
|
||||
rm -rf safestringlib
|
||||
git clone https://github.com/intel/safestringlib
|
||||
rm -rf safestringlib/{.git,unittests}
|
||||
git add safestringlib/
|
||||
```
|
|
@ -0,0 +1,17 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
|
@ -0,0 +1,220 @@
|
|||
#################
|
||||
## Eclipse
|
||||
#################
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
#################
|
||||
## GVIM & VI
|
||||
#################
|
||||
*~
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
build/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.log
|
||||
*.scc
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages Directory
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||
#packages/
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.[Pp]ublish.xml
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
#############
|
||||
## Windows detritus
|
||||
#############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
|
||||
|
||||
#############
|
||||
## Python
|
||||
#############
|
||||
|
||||
*.py[cod]
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist/
|
||||
build/
|
||||
eggs/
|
||||
parts/
|
||||
var/
|
||||
sdist/
|
||||
develop-eggs/
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
|
||||
#Translations
|
||||
*.mo
|
||||
|
||||
#Mr Developer
|
||||
.mr.developer.cfg
|
|
@ -0,0 +1,186 @@
|
|||
cmake_minimum_required(VERSION 3.1)
|
||||
project(safestring)
|
||||
|
||||
option(BUILD_UNITTESTS "Build also project unit-tests" OFF)
|
||||
|
||||
if (NOT DEFINED BUILD_OPT_DEFAULT)
|
||||
set (BUILD_OPT_DEFAULT YES CACHE PATH "Build option default")
|
||||
endif (NOT DEFINED BUILD_OPT_DEFAULT)
|
||||
|
||||
option(BUILD_MEMCMP "Build memcmp* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_MEMCPY "Build memcpy* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_MEMMOVE "Build memmove* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_MEMSET "Build memset* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_MEMZERO "Build memzero* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STPCPY "Build stpcpy* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STPNCPY "Build stpncpy* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCASECMP "Build strcasecmp* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCASESTR "Build strcasestr* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCAT "Build strcat* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCMPFLD "Build strcmpfld* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCMP "Build strcmp* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCPYFLDIN "Build strcpyfldin* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCPYFLDOUT "Build strcpyfldout* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCPYFLD "Build strcpyfld* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCPY "Build strcpy* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRCSPN "Build strcspn* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRFIRSTCHAR "Build strfirstchar* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRFIRSTDIFF "Build strfirstdiff* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRFIRSTSAME "Build strfirstsame* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRISALPHANUMERIC "Build strisalphanumeric* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRISASCII "Build strisascii* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRISDIGIT "Build strisdigit* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRISHEX "Build strishex* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRISLOWERCASE "Build strislowercase* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRISMIXEDCASE "Build strismixedcase* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRISPASSWORD "Build strispassword* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRISUPPERCASE "Build strisuppercase* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRLASTCHAR "Build strlastchar* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRLASTDIFF "Build strlastdiff* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRLASTSAME "Build strlastsame* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRLJUSTIFY "Build strljustify* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRNCAT "Build strncat* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRNCPY "Build strncpy* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRNLEN "Build strnlen* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRNTERMINATE "Build strnterminate* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRPBRK "Build strpbrk* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRPREFIX "Build strprefix* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRREMOVEWS "Build strremovews* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRSPN "Build strspn* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRSTR "Build strstr* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRTOK "Build strtok* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRTOLOWERCASE "Build strtolowercase* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRTOUPPERCASE "Build strtouppercase* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_STRZERO "Build strzero* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WCPCPY "Build wcpcpy* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WCSCAT "Build wcscat* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WCSCPY "Build wcscpy* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WCSNCAT "Build wcsncat* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WCSNCPY "Build wcsncpy* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WCSNLEN "Build wcsnlen* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WMEMCMP "Build wmemcmp* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WMEMCPY "Build wmemcpy* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WMEMMOVE "Build wmemmove* functions" ${BUILD_OPT_DEFAULT})
|
||||
option(BUILD_WMEMSET "Build wmemset* functions" ${BUILD_OPT_DEFAULT})
|
||||
|
||||
set(SOURCES
|
||||
safeclib/abort_handler_s.c
|
||||
safeclib/ignore_handler_s.c
|
||||
$<$<BOOL:${BUILD_MEMCMP}>:safeclib/memcmp16_s.c>
|
||||
$<$<BOOL:${BUILD_MEMCMP}>:safeclib/memcmp32_s.c>
|
||||
$<$<BOOL:${BUILD_MEMCMP}>:safeclib/memcmp_s.c>
|
||||
$<$<BOOL:${BUILD_MEMCPY}>:safeclib/memcpy16_s.c>
|
||||
$<$<BOOL:${BUILD_MEMCPY}>:safeclib/memcpy32_s.c>
|
||||
$<$<BOOL:${BUILD_MEMCPY}>:safeclib/memcpy_s.c>
|
||||
$<$<BOOL:${BUILD_MEMMOVE}>:safeclib/memmove16_s.c>
|
||||
$<$<BOOL:${BUILD_MEMMOVE}>:safeclib/memmove32_s.c>
|
||||
$<$<BOOL:${BUILD_MEMMOVE}>:safeclib/memmove_s.c>
|
||||
safeclib/mem_primitives_lib.c
|
||||
$<$<BOOL:${BUILD_MEMSET}>:safeclib/memset16_s.c>
|
||||
$<$<BOOL:${BUILD_MEMSET}>:safeclib/memset32_s.c>
|
||||
$<$<BOOL:${BUILD_MEMSET}>:safeclib/memset_s.c>
|
||||
$<$<BOOL:${BUILD_MEMZERO}>:safeclib/memzero16_s.c>
|
||||
$<$<BOOL:${BUILD_MEMZERO}>:safeclib/memzero32_s.c>
|
||||
$<$<BOOL:${BUILD_MEMZERO}>:safeclib/memzero_s.c>
|
||||
safeclib/safe_mem_constraint.c
|
||||
safeclib/safe_str_constraint.c
|
||||
safeclib/snprintf_support.c
|
||||
$<$<BOOL:${BUILD_STPCPY}>:safeclib/stpcpy_s.c>
|
||||
$<$<BOOL:${BUILD_STPNCPY}>:safeclib/stpncpy_s.c>
|
||||
$<$<BOOL:${BUILD_STRCASECMP}>:safeclib/strcasecmp_s.c>
|
||||
$<$<BOOL:${BUILD_STRCASESTR}>:safeclib/strcasestr_s.c>
|
||||
$<$<BOOL:${BUILD_STRCAT}>:safeclib/strcat_s.c>
|
||||
$<$<BOOL:${BUILD_STRCMPFLD}>:safeclib/strcmpfld_s.c>
|
||||
$<$<BOOL:${BUILD_STRCMP}>:safeclib/strcmp_s.c>
|
||||
$<$<BOOL:${BUILD_STRCPYFLDIN}>:safeclib/strcpyfldin_s.c>
|
||||
$<$<BOOL:${BUILD_STRCPYFLDOUT}>:safeclib/strcpyfldout_s.c>
|
||||
$<$<BOOL:${BUILD_STRCPYFLD}>:safeclib/strcpyfld_s.c>
|
||||
$<$<BOOL:${BUILD_STRCPY}>:safeclib/strcpy_s.c>
|
||||
$<$<BOOL:${BUILD_STRCSPN}>:safeclib/strcspn_s.c>
|
||||
$<$<BOOL:${BUILD_STRFIRSTCHAR}>:safeclib/strfirstchar_s.c>
|
||||
$<$<BOOL:${BUILD_STRFIRSTDIFF}>:safeclib/strfirstdiff_s.c>
|
||||
$<$<BOOL:${BUILD_STRFIRSTSAME}>:safeclib/strfirstsame_s.c>
|
||||
$<$<BOOL:${BUILD_STRISALPHANUMERIC}>:safeclib/strisalphanumeric_s.c>
|
||||
$<$<BOOL:${BUILD_STRISASCII}>:safeclib/strisascii_s.c>
|
||||
$<$<BOOL:${BUILD_STRISDIGIT}>:safeclib/strisdigit_s.c>
|
||||
$<$<BOOL:${BUILD_STRISHEX}>:safeclib/strishex_s.c>
|
||||
$<$<BOOL:${BUILD_STRISLOWERCASE}>:safeclib/strislowercase_s.c>
|
||||
$<$<BOOL:${BUILD_STRISMIXEDCASE}>:safeclib/strismixedcase_s.c>
|
||||
$<$<BOOL:${BUILD_STRISPASSWORD}>:safeclib/strispassword_s.c>
|
||||
$<$<BOOL:${BUILD_STRISUPPERCASE}>:safeclib/strisuppercase_s.c>
|
||||
$<$<BOOL:${BUILD_STRLASTCHAR}>:safeclib/strlastchar_s.c>
|
||||
$<$<BOOL:${BUILD_STRLASTDIFF}>:safeclib/strlastdiff_s.c>
|
||||
$<$<BOOL:${BUILD_STRLASTSAME}>:safeclib/strlastsame_s.c>
|
||||
$<$<BOOL:${BUILD_STRLJUSTIFY}>:safeclib/strljustify_s.c>
|
||||
$<$<BOOL:${BUILD_STRNCAT}>:safeclib/strncat_s.c>
|
||||
$<$<BOOL:${BUILD_STRNCPY}>:safeclib/strncpy_s.c>
|
||||
$<$<BOOL:${BUILD_STRNLEN}>:safeclib/strnlen_s.c>
|
||||
$<$<BOOL:${BUILD_STRNTERMINATE}>:safeclib/strnterminate_s.c>
|
||||
$<$<BOOL:${BUILD_STRPBRK}>:safeclib/strpbrk_s.c>
|
||||
$<$<BOOL:${BUILD_STRPREFIX}>:safeclib/strprefix_s.c>
|
||||
$<$<BOOL:${BUILD_STRREMOVEWS}>:safeclib/strremovews_s.c>
|
||||
$<$<BOOL:${BUILD_STRSPN}>:safeclib/strspn_s.c>
|
||||
$<$<BOOL:${BUILD_STRSTR}>:safeclib/strstr_s.c>
|
||||
$<$<BOOL:${BUILD_STRTOK}>:safeclib/strtok_s.c>
|
||||
$<$<BOOL:${BUILD_STRTOLOWERCASE}>:safeclib/strtolowercase_s.c>
|
||||
$<$<BOOL:${BUILD_STRTOUPPERCASE}>:safeclib/strtouppercase_s.c>
|
||||
$<$<BOOL:${BUILD_STRZERO}>:safeclib/strzero_s.c>
|
||||
$<$<BOOL:${BUILD_WCPCPY}>:safeclib/wcpcpy_s.c>
|
||||
$<$<BOOL:${BUILD_WCSCAT}>:safeclib/wcscat_s.c>
|
||||
$<$<BOOL:${BUILD_WCSCPY}>:safeclib/wcscpy_s.c>
|
||||
$<$<BOOL:${BUILD_WCSNCAT}>:safeclib/wcsncat_s.c>
|
||||
$<$<BOOL:${BUILD_WCSNCPY}>:safeclib/wcsncpy_s.c>
|
||||
$<$<BOOL:${BUILD_WCSNLEN}>:safeclib/wcsnlen_s.c>
|
||||
$<$<BOOL:${BUILD_WMEMCMP}>:safeclib/wmemcmp_s.c>
|
||||
$<$<BOOL:${BUILD_WMEMCPY}>:safeclib/wmemcpy_s.c>
|
||||
$<$<BOOL:${BUILD_WMEMMOVE}>:safeclib/wmemmove_s.c>
|
||||
$<$<BOOL:${BUILD_WMEMSET}>:safeclib/wmemset_s.c>
|
||||
)
|
||||
|
||||
include_directories(include)
|
||||
|
||||
add_library(${PROJECT_NAME}_objlib OBJECT ${SOURCES})
|
||||
set_target_properties(${PROJECT_NAME}_objlib
|
||||
PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}_objlib PRIVATE -DSTDC_HEADERS)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}_objlib
|
||||
PRIVATE -Wno-unknown-pragmas -Wno-unused-parameter)
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 7)
|
||||
target_compile_options(${PROJECT_NAME}_objlib
|
||||
PRIVATE -Wno-implicit-fallthrough)
|
||||
endif()
|
||||
target_compile_options(${PROJECT_NAME}_objlib
|
||||
PRIVATE -Wall -Wextra -Wsign-compare -Wformat-security)
|
||||
target_compile_options(${PROJECT_NAME}_objlib
|
||||
PRIVATE -Wstack-protector -Winit-self)
|
||||
target_compile_options(${PROJECT_NAME}_objlib
|
||||
PRIVATE -D_FORTIFY_SOURCE=2 -O2)
|
||||
target_compile_options(${PROJECT_NAME}_objlib
|
||||
PRIVATE -fstack-protector-all)
|
||||
target_compile_options(${PROJECT_NAME}_objlib
|
||||
PRIVATE --param ssp-buffer-size=4 -ftrapv)
|
||||
target_compile_options(${PROJECT_NAME}_objlib PRIVATE -fPIE -fPIC)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 6)
|
||||
target_compile_options(${PROJECT_NAME}_objlib PRIVATE -mmitigate-rop)
|
||||
endif()
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack -z relro -z now")
|
||||
|
||||
option(BUILD_ERROR_ON_WARNING "Fail compilation on warning" OFF)
|
||||
|
||||
if(BUILD_ERROR_ON_WARNING)
|
||||
target_compile_options(${PROJECT_NAME}_objlib PRIVATE -Werror)
|
||||
endif()
|
||||
|
||||
target_compile_options(${PROJECT_NAME}_objlib PRIVATE $<$<CONFIG:RELEASE>:-s>)
|
||||
|
||||
add_library(${PROJECT_NAME}_shared SHARED $<TARGET_OBJECTS:${PROJECT_NAME}_objlib>)
|
||||
add_library(${PROJECT_NAME}_static STATIC $<TARGET_OBJECTS:${PROJECT_NAME}_objlib>)
|
||||
target_include_directories(${PROJECT_NAME}_shared PUBLIC include)
|
||||
target_include_directories(${PROJECT_NAME}_static PUBLIC include)
|
||||
|
||||
if(BUILD_UNITTESTS)
|
||||
add_subdirectory(unittests)
|
||||
endif()
|
|
@ -0,0 +1,46 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at webmaster@linux.intel.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
|
@ -0,0 +1,47 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2014-2018 Intel Corporation
|
||||
|
||||
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.
|
||||
|
||||
================================================================================
|
||||
|
||||
Copyright (C) 2012, 2013 Cisco Systems
|
||||
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.
|
|
@ -0,0 +1,50 @@
|
|||
Safe C Library
|
||||
|
||||
Copyright (c) 2014-2016, Intel Corporation. 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.
|
||||
|
||||
================================================================================
|
||||
|
||||
Copyright (C) 2012, 2013 Cisco Systems
|
||||
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.
|
|
@ -0,0 +1,86 @@
|
|||
# safestringlib
|
||||
The Secure Development Lifecycle (SDL) recommends banning certain C Library functions because they directly contribute
|
||||
to security vulnerabilities such as buffer overflows. However routines for the manipulation of strings and memory buffers
|
||||
are common in software and firmware, and are essential to accomplish certain programming tasks. Safer replacements for
|
||||
these functions that avoid or prevent serious security vulnerabilities (e.g. buffer overflows, string format attacks,
|
||||
conversion overflows/underflows, etc.) are available in the SafeString Library.
|
||||
|
||||
This library includes routines for safe string operations (like strcpy) and memory routines (like memcpy) that are
|
||||
recommended for Linux/Android operating systems, and will also work for Windows. This library is especially useful for
|
||||
cross-platform situations where one library for these routines is preferred.
|
||||
|
||||
The Safe String Library is based on the Safe C Library by Cisco, and includes replacement C Library functions for the SDL
|
||||
banned functions, as well as a number of additional useful routines that are also susceptible to buffer overflows. This
|
||||
library continues to be made available under the MIT Open Source License.
|
||||
|
||||
Cisco's Safe C Library was extended by Intel's Security Center of Excellence (SeCoE) to add additional routines, and
|
||||
include additional unit tests.
|
||||
|
||||
LIST OF PRIMARY FUNCTIONS:
|
||||
-----------------------------
|
||||
* memcmp_s()
|
||||
* memcpy_s()
|
||||
* memmove_s()
|
||||
* memset_s()
|
||||
* memzero_s()
|
||||
|
||||
* stpcpy_s()
|
||||
* stpncpy_s()
|
||||
* strcat_s()
|
||||
* strcpy_s()
|
||||
* strcspn_s()
|
||||
* strncat_s()
|
||||
* strncpy_s()
|
||||
* strnlen_s()
|
||||
* strpbrk_s()
|
||||
* strspn_s()
|
||||
* strstr_s()
|
||||
* strtok_s()
|
||||
|
||||
* wcpcpy_s()
|
||||
* wcscat_s()
|
||||
* wcscpy_s()
|
||||
* wcsncat_s()
|
||||
* wcsnlen_s()
|
||||
* wmemcmp_s()
|
||||
* wmemcpy_s()
|
||||
* wmemmove_s()
|
||||
* wmemset_s()
|
||||
|
||||
|
||||
LIST OF ADDITIONAL STRING ROUTINES:
|
||||
------------------------------------
|
||||
* strcasecmp_s()
|
||||
* strcasestr_s()
|
||||
* strcmp_s()
|
||||
* strcmpfld_s()
|
||||
* strcpyfld_s()
|
||||
* strcpyfldin_s()
|
||||
* strcpyfldout_s()
|
||||
* strfirstchar_s()
|
||||
* strfirstdiff_s()
|
||||
* strfirstsmae_s()
|
||||
* strisalphanumeric_s()
|
||||
* strisascii_s()
|
||||
* strisdigit_s()
|
||||
* strishes_s()
|
||||
* strislowercase_s()
|
||||
* strismixedcase_s()
|
||||
* strispassword_s()
|
||||
* strisuppercase_s()
|
||||
* strlastchar_s()
|
||||
* strlastdiff_s()
|
||||
* strlastsame_s()
|
||||
* strljustify_s()
|
||||
* strnterminate_s()
|
||||
* strprefix_s()
|
||||
* stremovews_s()
|
||||
* strtolowercase_s()
|
||||
* strtouppercase_s()
|
||||
* strzero_s()
|
||||
|
||||
|
||||
PLANNED ENHANCEMENTS:
|
||||
----------------------
|
||||
- Add full sprintf_s() support
|
||||
- Add full sscanf_s() support
|
|
@ -0,0 +1,68 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_lib.h -- Safe C Library
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
* Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2008-2013 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_LIB_H__
|
||||
#define __SAFE_LIB_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "safe_types.h"
|
||||
#include "safe_lib_errno.h"
|
||||
|
||||
/* C11 appendix K types - specific for bounds checking */
|
||||
typedef size_t rsize_t;
|
||||
|
||||
/*
|
||||
* We depart from the standard and allow memory and string operations to
|
||||
* have different max sizes. See the respective safe_mem_lib.h or
|
||||
* safe_str_lib.h files.
|
||||
*/
|
||||
/* #define RSIZE_MAX (~(rsize_t)0) - leave here for completeness */
|
||||
|
||||
typedef void (*constraint_handler_t) (const char * /* msg */,
|
||||
void * /* ptr */,
|
||||
errno_t /* error */);
|
||||
|
||||
extern void abort_handler_s(const char *msg, void *ptr, errno_t error);
|
||||
extern void ignore_handler_s(const char *msg, void *ptr, errno_t error);
|
||||
|
||||
#define sl_default_handler ignore_handler_s
|
||||
|
||||
#include "safe_mem_lib.h"
|
||||
#include "safe_str_lib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __SAFE_LIB_H__ */
|
|
@ -0,0 +1,100 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_lib_errno.h -- Safe C Lib Error codes
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
* Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2008-2013 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_LIB_ERRNO_H__
|
||||
#define __SAFE_LIB_ERRNO_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
# include <linux/errno.h>
|
||||
#else
|
||||
#include <errno.h>
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/*
|
||||
* Safe Lib specific errno codes. These can be added to the errno.h file
|
||||
* if desired.
|
||||
*/
|
||||
#ifndef ESNULLP
|
||||
#define ESNULLP ( 400 ) /* null ptr */
|
||||
#endif
|
||||
|
||||
#ifndef ESZEROL
|
||||
#define ESZEROL ( 401 ) /* length is zero */
|
||||
#endif
|
||||
|
||||
#ifndef ESLEMIN
|
||||
#define ESLEMIN ( 402 ) /* length is below min */
|
||||
#endif
|
||||
|
||||
#ifndef ESLEMAX
|
||||
#define ESLEMAX ( 403 ) /* length exceeds max */
|
||||
#endif
|
||||
|
||||
#ifndef ESOVRLP
|
||||
#define ESOVRLP ( 404 ) /* overlap undefined */
|
||||
#endif
|
||||
|
||||
#ifndef ESEMPTY
|
||||
#define ESEMPTY ( 405 ) /* empty string */
|
||||
#endif
|
||||
|
||||
#ifndef ESNOSPC
|
||||
#define ESNOSPC ( 406 ) /* not enough space for s2 */
|
||||
#endif
|
||||
|
||||
#ifndef ESUNTERM
|
||||
#define ESUNTERM ( 407 ) /* unterminated string */
|
||||
#endif
|
||||
|
||||
#ifndef ESNODIFF
|
||||
#define ESNODIFF ( 408 ) /* no difference */
|
||||
#endif
|
||||
|
||||
#ifndef ESNOTFND
|
||||
#define ESNOTFND ( 409 ) /* not found */
|
||||
#endif
|
||||
|
||||
/* Additional for safe snprintf_s interfaces */
|
||||
#ifndef ESBADFMT
|
||||
#define ESBADFMT ( 410 ) /* bad format string */
|
||||
#endif
|
||||
|
||||
#ifndef ESFMTTYP
|
||||
#define ESFMTTYP ( 411 ) /* bad format type */
|
||||
#endif
|
||||
|
||||
/* EOK may or may not be defined in errno.h */
|
||||
#ifndef EOK
|
||||
#define EOK ( 0 )
|
||||
#endif
|
||||
|
||||
#endif /* __SAFE_LIB_ERRNO_H__ */
|
|
@ -0,0 +1,91 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_lib_errno.h -- Safe C Lib Error codes
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
* Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2008-2013 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_LIB_ERRNO_H__
|
||||
#define __SAFE_LIB_ERRNO_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
# include <linux/errno.h>
|
||||
#else
|
||||
@INSERT_ERRNO_H@
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/*
|
||||
* Safe Lib specific errno codes. These can be added to the errno.h file
|
||||
* if desired.
|
||||
*/
|
||||
#ifndef ESNULLP
|
||||
#define ESNULLP ( 400 ) /* null ptr */
|
||||
#endif
|
||||
|
||||
#ifndef ESZEROL
|
||||
#define ESZEROL ( 401 ) /* length is zero */
|
||||
#endif
|
||||
|
||||
#ifndef ESLEMIN
|
||||
#define ESLEMIN ( 402 ) /* length is below min */
|
||||
#endif
|
||||
|
||||
#ifndef ESLEMAX
|
||||
#define ESLEMAX ( 403 ) /* length exceeds max */
|
||||
#endif
|
||||
|
||||
#ifndef ESOVRLP
|
||||
#define ESOVRLP ( 404 ) /* overlap undefined */
|
||||
#endif
|
||||
|
||||
#ifndef ESEMPTY
|
||||
#define ESEMPTY ( 405 ) /* empty string */
|
||||
#endif
|
||||
|
||||
#ifndef ESNOSPC
|
||||
#define ESNOSPC ( 406 ) /* not enough space for s2 */
|
||||
#endif
|
||||
|
||||
#ifndef ESUNTERM
|
||||
#define ESUNTERM ( 407 ) /* unterminated string */
|
||||
#endif
|
||||
|
||||
#ifndef ESNODIFF
|
||||
#define ESNODIFF ( 408 ) /* no difference */
|
||||
#endif
|
||||
|
||||
#ifndef ESNOTFND
|
||||
#define ESNOTFND ( 409 ) /* not found */
|
||||
#endif
|
||||
|
||||
/* EOK may or may not be defined in errno.h */
|
||||
#ifndef EOK
|
||||
#define EOK ( 0 )
|
||||
#endif
|
||||
|
||||
#endif /* __SAFE_LIB_ERRNO_H__ */
|
|
@ -0,0 +1,122 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_mem_lib.h -- Safe C Library Memory APIs
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
* Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2008-2012 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_MEM_LIB_H__
|
||||
#define __SAFE_MEM_LIB_H__
|
||||
|
||||
#include "safe_lib.h"
|
||||
#include <wchar.h>
|
||||
|
||||
#define RSIZE_MAX_MEM ( 256UL << 20 ) /* 256MB */
|
||||
#define RSIZE_MAX_MEM16 ( RSIZE_MAX_MEM/2 )
|
||||
#define RSIZE_MAX_MEM32 ( RSIZE_MAX_MEM/4 )
|
||||
|
||||
/* set memory constraint handler */
|
||||
extern constraint_handler_t
|
||||
set_mem_constraint_handler_s(constraint_handler_t handler);
|
||||
|
||||
|
||||
/* compare memory */
|
||||
extern errno_t memcmp_s(const void *dest, rsize_t dmax,
|
||||
const void *src, rsize_t slen, int *diff);
|
||||
|
||||
/* compare uint16_t memory */
|
||||
extern errno_t memcmp16_s(const uint16_t *dest, rsize_t dmax,
|
||||
const uint16_t *src, rsize_t slen, int *diff);
|
||||
|
||||
/* compare uint32_t memory */
|
||||
extern errno_t memcmp32_s(const uint32_t *dest, rsize_t dmax,
|
||||
const uint32_t *src, rsize_t slen, int *diff);
|
||||
|
||||
/* wide compare memory */
|
||||
extern errno_t wmemcmp_s(const wchar_t *dest, rsize_t dmax,
|
||||
const wchar_t *src, rsize_t smax, int *diff);
|
||||
|
||||
|
||||
/* copy memory */
|
||||
extern errno_t memcpy_s(void *dest, rsize_t dmax,
|
||||
const void *src, rsize_t slen);
|
||||
|
||||
/* copy uint16_t memory */
|
||||
extern errno_t memcpy16_s(uint16_t *dest, rsize_t dmax,
|
||||
const uint16_t *src, rsize_t slen);
|
||||
|
||||
/* copy uint32_t memory */
|
||||
extern errno_t memcpy32_s(uint32_t *dest, rsize_t dmax,
|
||||
const uint32_t *src, rsize_t slen);
|
||||
|
||||
/* copy wchar_t memory */
|
||||
extern errno_t wmemcpy_s(wchar_t *dest, rsize_t dmax,
|
||||
const wchar_t *src, rsize_t slen);
|
||||
|
||||
|
||||
/* move memory, including overlapping memory */
|
||||
extern errno_t memmove_s(void *dest, rsize_t dmax,
|
||||
const void *src, rsize_t slen);
|
||||
|
||||
/* uint16_t move memory, including overlapping memory */
|
||||
extern errno_t memmove16_s(uint16_t *dest, rsize_t dmax,
|
||||
const uint16_t *src, rsize_t slen);
|
||||
|
||||
/* uint32_t move memory, including overlapping memory */
|
||||
extern errno_t memmove32_s(uint32_t *dest, rsize_t dmax,
|
||||
const uint32_t *src, rsize_t slen);
|
||||
|
||||
/* copy wchar_t memory, including overlapping memory */
|
||||
extern errno_t wmemmove_s(wchar_t *dest, rsize_t dmax,
|
||||
const wchar_t *src, rsize_t slen);
|
||||
|
||||
|
||||
/* set bytes */
|
||||
extern errno_t memset_s(void *dest, rsize_t dmax, uint8_t value);
|
||||
|
||||
/* set uint16_t */
|
||||
extern errno_t memset16_s(uint16_t *dest, rsize_t dmax, uint16_t value);
|
||||
|
||||
/* set uint32_t */
|
||||
extern errno_t memset32_s(uint32_t *dest, rsize_t dmax, uint32_t value);
|
||||
|
||||
/* wide set bytes */
|
||||
extern errno_t wmemset_s(wchar_t *dest, wchar_t value, rsize_t len);
|
||||
|
||||
|
||||
/* byte zero */
|
||||
extern errno_t memzero_s(void *dest, rsize_t dmax);
|
||||
|
||||
/* uint16_t zero */
|
||||
extern errno_t memzero16_s(uint16_t *dest, rsize_t dmax);
|
||||
|
||||
/* uint32_t zero */
|
||||
extern errno_t memzero32_s(uint32_t *dest, rsize_t dmax);
|
||||
|
||||
|
||||
#endif /* __SAFE_MEM_LIB_H__ */
|
|
@ -0,0 +1,293 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_str_lib.h -- Safe C Library String APIs
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011, 2013 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_STR_LIB_H__
|
||||
#define __SAFE_STR_LIB_H__
|
||||
|
||||
#include "safe_lib.h"
|
||||
#include <wchar.h>
|
||||
|
||||
/*
|
||||
* The shortest string is a null string!!
|
||||
*/
|
||||
#define RSIZE_MIN_STR ( 1 )
|
||||
|
||||
/* maximum sring length */
|
||||
#define RSIZE_MAX_STR ( 4UL << 10 ) /* 4KB */
|
||||
|
||||
|
||||
/* The makeup of a password */
|
||||
#define SAFE_STR_MIN_LOWERCASE ( 2 )
|
||||
#define SAFE_STR_MIN_UPPERCASE ( 2 )
|
||||
#define SAFE_STR_MIN_NUMBERS ( 1 )
|
||||
#define SAFE_STR_MIN_SPECIALS ( 1 )
|
||||
|
||||
#define SAFE_STR_PASSWORD_MIN_LENGTH ( 6 )
|
||||
#define SAFE_STR_PASSWORD_MAX_LENGTH ( 32 )
|
||||
|
||||
|
||||
/* set string constraint handler */
|
||||
extern constraint_handler_t
|
||||
set_str_constraint_handler_s(constraint_handler_t handler);
|
||||
|
||||
|
||||
/* string compare */
|
||||
extern errno_t
|
||||
strcasecmp_s(const char *dest, rsize_t dmax,
|
||||
const char *src, int *indicator);
|
||||
|
||||
|
||||
/* find a substring _ case insensitive */
|
||||
extern errno_t
|
||||
strcasestr_s(char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t slen, char **substring);
|
||||
|
||||
|
||||
/* string concatenate */
|
||||
extern errno_t
|
||||
strcat_s(char *dest, rsize_t dmax, const char *src);
|
||||
|
||||
|
||||
/* string compare */
|
||||
extern errno_t
|
||||
strcmp_s(const char *dest, rsize_t dmax,
|
||||
const char *src, int *indicator);
|
||||
|
||||
|
||||
/* fixed field string compare */
|
||||
extern errno_t
|
||||
strcmpfld_s(const char *dest, rsize_t dmax,
|
||||
const char *src, int *indicator);
|
||||
|
||||
|
||||
/* string copy */
|
||||
extern errno_t
|
||||
strcpy_s(char *dest, rsize_t dmax, const char *src);
|
||||
|
||||
/* string copy */
|
||||
extern char *
|
||||
stpcpy_s(char *dest, rsize_t dmax, const char *src, errno_t *err);
|
||||
|
||||
/* string copy */
|
||||
extern char *
|
||||
stpncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t smax, errno_t *err);
|
||||
|
||||
/* fixed char array copy */
|
||||
extern errno_t
|
||||
strcpyfld_s(char *dest, rsize_t dmax, const char *src, rsize_t slen);
|
||||
|
||||
|
||||
/* copy from a null terminated string to fixed char array */
|
||||
extern errno_t
|
||||
strcpyfldin_s(char *dest, rsize_t dmax, const char *src, rsize_t slen);
|
||||
|
||||
|
||||
/* copy from a char array to null terminated string */
|
||||
extern errno_t
|
||||
strcpyfldout_s(char *dest, rsize_t dmax, const char *src, rsize_t slen);
|
||||
|
||||
|
||||
/* computes excluded prefix length */
|
||||
extern errno_t
|
||||
strcspn_s(const char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t slen, rsize_t *count);
|
||||
|
||||
|
||||
/* returns a pointer to the first occurrence of c in dest */
|
||||
extern errno_t
|
||||
strfirstchar_s(char *dest, rsize_t dmax, char c, char **first);
|
||||
|
||||
|
||||
/* returns index of first difference */
|
||||
extern errno_t
|
||||
strfirstdiff_s(const char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t *index);
|
||||
|
||||
|
||||
/* validate alphanumeric string */
|
||||
extern bool
|
||||
strisalphanumeric_s(const char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* validate ascii string */
|
||||
extern bool
|
||||
strisascii_s(const char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* validate string of digits */
|
||||
extern bool
|
||||
strisdigit_s(const char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* validate hex string */
|
||||
extern bool
|
||||
strishex_s(const char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* validate lower case */
|
||||
extern bool
|
||||
strislowercase_s(const char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* validate mixed case */
|
||||
extern bool
|
||||
strismixedcase_s(const char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* validate password */
|
||||
extern bool
|
||||
strispassword_s(const char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* validate upper case */
|
||||
extern bool
|
||||
strisuppercase_s(const char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* returns a pointer to the last occurrence of c in s1 */
|
||||
extern errno_t
|
||||
strlastchar_s(char *str, rsize_t smax, char c, char **first);
|
||||
|
||||
|
||||
/* returns index of last difference */
|
||||
extern errno_t
|
||||
strlastdiff_s(const char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t *index);
|
||||
|
||||
|
||||
/* left justify */
|
||||
extern errno_t
|
||||
strljustify_s(char *dest, rsize_t dmax);
|
||||
|
||||
|
||||
/* fitted string concatenate */
|
||||
extern errno_t
|
||||
strncat_s(char *dest, rsize_t dmax, const char *src, rsize_t slen);
|
||||
|
||||
|
||||
/* fitted string copy */
|
||||
extern errno_t
|
||||
strncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t slen);
|
||||
|
||||
|
||||
/* string length */
|
||||
extern rsize_t
|
||||
strnlen_s (const char *s, rsize_t smax);
|
||||
|
||||
|
||||
/* string terminate */
|
||||
extern rsize_t
|
||||
strnterminate_s (char *s, rsize_t smax);
|
||||
|
||||
|
||||
/* get pointer to first occurrence from set of char */
|
||||
extern errno_t
|
||||
strpbrk_s(char *dest, rsize_t dmax,
|
||||
char *src, rsize_t slen, char **first);
|
||||
|
||||
|
||||
extern errno_t
|
||||
strfirstsame_s(const char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t *index);
|
||||
|
||||
extern errno_t
|
||||
strlastsame_s(const char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t *index);
|
||||
|
||||
|
||||
/* searches for a prefix */
|
||||
extern errno_t
|
||||
strprefix_s(const char *dest, rsize_t dmax, const char *src);
|
||||
|
||||
|
||||
/* removes leading and trailing white space */
|
||||
extern errno_t
|
||||
strremovews_s(char *dest, rsize_t dmax);
|
||||
|
||||
|
||||
/* computes inclusive prefix length */
|
||||
extern errno_t
|
||||
strspn_s(const char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t slen, rsize_t *count);
|
||||
|
||||
|
||||
/* find a substring */
|
||||
extern errno_t
|
||||
strstr_s(char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t slen, char **substring);
|
||||
|
||||
|
||||
/* string tokenizer */
|
||||
extern char *
|
||||
strtok_s(char *s1, rsize_t *s1max, const char *src, char **ptr);
|
||||
|
||||
|
||||
/* convert string to lowercase */
|
||||
extern errno_t
|
||||
strtolowercase_s(char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* convert string to uppercase */
|
||||
extern errno_t
|
||||
strtouppercase_s(char *str, rsize_t slen);
|
||||
|
||||
|
||||
/* zero an entire string with nulls */
|
||||
extern errno_t
|
||||
strzero_s(char *dest, rsize_t dmax);
|
||||
|
||||
|
||||
/* wide string copy */
|
||||
extern wchar_t *
|
||||
wcpcpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, errno_t *err);
|
||||
|
||||
/* wide string concatenate */
|
||||
extern errno_t
|
||||
wcscat_s(wchar_t* dest, rsize_t dmax, const wchar_t* src);
|
||||
|
||||
/* fitted wide string concatenate */
|
||||
extern errno_t
|
||||
wcsncat_s(wchar_t *dest, rsize_t dmax, const wchar_t *src, rsize_t slen);
|
||||
|
||||
/* wide string copy */
|
||||
errno_t
|
||||
wcscpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src);
|
||||
|
||||
/* fitted wide string copy */
|
||||
extern errno_t
|
||||
wcsncpy_s(wchar_t* dest, rsize_t dmax, const wchar_t* src, rsize_t slen);
|
||||
|
||||
/* wide string length */
|
||||
extern rsize_t
|
||||
wcsnlen_s(const wchar_t *dest, rsize_t dmax);
|
||||
|
||||
|
||||
#endif /* __SAFE_STR_LIB_H__ */
|
|
@ -0,0 +1,68 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_types.h - C99 std types & defs or Linux kernel equivalents
|
||||
*
|
||||
* March 2007, Bo Berry
|
||||
* Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2007-2013 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_TYPES_H__
|
||||
#define __SAFE_TYPES_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* linux kernel environment */
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
/* errno_t isn't defined in the kernel */
|
||||
typedef int errno_t;
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* For systems without sys/types.h, prefer to get size_t from stdlib.h */
|
||||
/* some armcc environments don't have a sys/types.h in the environment */
|
||||
#ifdef _USE_STDLIB
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef int errno_t;
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __SAFE_TYPES_H__ */
|
|
@ -0,0 +1,59 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_types.h - C99 std types & defs or Linux kernel equivalents
|
||||
*
|
||||
* March 2007, Bo Berry
|
||||
* Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2007-2013 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_TYPES_H__
|
||||
#define __SAFE_TYPES_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* linux kernel environment */
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
/* errno_t isn't defined in the kernel */
|
||||
typedef int errno_t;
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
@INSERT_SYS_TYPES_H@
|
||||
@INSERT_INTTYPES_H@
|
||||
@INSERT_STDINT_H@
|
||||
@INSERT_ERRNO_H@
|
||||
|
||||
@FALLBACK_ERRNO_T@
|
||||
|
||||
@INSERT_BOOL_SUPPORT@
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __SAFE_TYPES_H__ */
|
|
@ -0,0 +1,48 @@
|
|||
/*------------------------------------------------------------------
|
||||
* sprintf_s.h -- Safe Sprintf Interfaces
|
||||
*
|
||||
* August 2014, D Wheeler
|
||||
*
|
||||
* Copyright (c) 2014 by Intel Corp
|
||||
* 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SPRINTF_S_H_
|
||||
#define SPRINTF_S_H_
|
||||
|
||||
#include <safe_lib_errno.h>
|
||||
|
||||
|
||||
#define SNPRFNEGATE(x) (-1*(x))
|
||||
|
||||
|
||||
|
||||
int snprintf_s_i(char *dest, rsize_t dmax, const char *format, int a);
|
||||
int snprintf_s_si(char *dest, rsize_t dmax, const char *format, char *s, int a);
|
||||
int snprintf_s_l(char *dest, rsize_t dmax, const char *format, long a);
|
||||
int snprintf_s_sl(char *dest, rsize_t dmax, const char *format, char *s, long a);
|
||||
|
||||
|
||||
|
||||
#endif /* SPRINTF_S_H_ */
|
|
@ -0,0 +1,69 @@
|
|||
IDIR = include
|
||||
MKDIR_P = mkdir -p
|
||||
CC=gcc
|
||||
CFLAGS=-I$(IDIR) -fstack-protector-strong -fPIE -fPIC -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security
|
||||
LDFLAGS=-z noexecstack -z relo -z now
|
||||
|
||||
ODIR=obj
|
||||
OTDIR=objtest
|
||||
SRCDIR=safeclib
|
||||
TESTDIR=unittests
|
||||
|
||||
|
||||
_DEPS = safe_lib_errno.h safe_lib.h safe_str_lib.h safe_types.h.in safe_lib_errno.h.in safe_mem_lib.h safe_types.h
|
||||
|
||||
_ODEPS = mem_primitives_lib.h safeclib_private.h safe_mem_constraint.h safe_str_constraint.h
|
||||
|
||||
all: directories libsafestring.a safestringtest
|
||||
|
||||
|
||||
DEPS = $(addprefix $(IDIR)/,$(_DEPS))
|
||||
ODEPS = $(addprefix $(SRCDIR)/,$(_ODEPS))
|
||||
|
||||
|
||||
_CLIB = abort_handler_s.c stpcpy_s.c strlastsame_s.c ignore_handler_s.c stpncpy_s.c strljustify_s.c memcmp16_s.c strcasecmp_s.c strncat_s.c memcmp32_s.c strcasestr_s.c strncpy_s.c memcmp_s.c strcat_s.c strnlen_s.c memcpy16_s.c strcmpfld_s.c strnterminate_s.c memcpy32_s.c strcmp_s.c strpbrk_s.c memcpy_s.c strcpyfldin_s.c strprefix_s.c memmove16_s.c strcpyfldout_s.c strremovews_s.c memmove32_s.c strcpyfld_s.c strspn_s.c memmove_s.c strcpy_s.c strstr_s.c mem_primitives_lib.c strcspn_s.c strtok_s.c strfirstchar_s.c strtolowercase_s.c memset16_s.c strfirstdiff_s.c strtouppercase_s.c memset32_s.c strfirstsame_s.c strzero_s.c memset_s.c strisalphanumeric_s.c wcpcpy_s.c memzero16_s.c strisascii_s.c wcscat_s.c memzero32_s.c strisdigit_s.c wcscpy_s.c memzero_s.c strishex_s.c wcsncat_s.c strislowercase_s.c wcsncpy_s.c safe_mem_constraint.c strismixedcase_s.c wcsnlen_s.c strispassword_s.c wmemcmp_s.c safe_str_constraint.c strisuppercase_s.c wmemcpy_s.c strlastchar_s.c wmemmove_s.c snprintf_support.c strlastdiff_s.c wmemset_s.c
|
||||
|
||||
_TLIST = $(addprefix $(ODIR)/,$(_CLIB))
|
||||
OBJ = $(patsubst %.c,%.o,$(_TLIST))
|
||||
CLIB =$(addprefix $(SRCDIR)/,$(_CLIB))
|
||||
|
||||
|
||||
|
||||
$(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS) $(ODEPS)
|
||||
$(CC) $(LDFLAGS) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
libsafestring.a: $(OBJ)
|
||||
ar rcs $@ $^
|
||||
|
||||
|
||||
_TESTFUNCS = Safe_String_UnitTestMain.c test_strcmp_s.c test_strnlen_s.c test_memcmp16_s.c test_strcpyfldin_s.c test_strnterminate_s.c test_memcmp32_s.c test_strcpyfldout_s.c test_strpbrk_s.c test_memcmp_s.c test_strcpyfld_s.c test_strprefix_s.c test_memcpy16_s.c test_strcpy_s.c test_strremovews_s.c test_memcpy32_s.c test_strcspn_s.c test_strspn_s.c test_memcpy_s.c test_strfirstchar_s.c test_strstr_s.c test_memmove16_s.c test_strfirstdiff_s.c test_strtok_s.c test_memmove32_s.c test_strfirstsame_s.c test_strtolowercase_s.c test_memmove_s.c test_strisalphanumeric_s.c test_strtouppercase_s.c test_memset16_s.c test_strisascii_s.c test_strzero_s.c test_memset32_s.c test_strisdigit_s.c test_wcpcpy_s.c test_memset_s.c test_strishex_s.c test_wcscat_s.c test_memzero16_s.c test_strislowercase_s.c test_wcscpy_s.c test_memzero32_s.c test_strismixed_s.c test_wcsncat_s.c test_memzero_s.c test_strispassword_s.c test_wcsncpy_s.c test_strisuppercase_s.c test_wcsnlen_s.c test_stpcpy_s.c test_strlastchar_s.c test_wmemcmp_s.c test_stpncpy_s.c test_strlastdiff_s.c test_wmemcpy_s.c test_strcasecmp_s.c test_strlastsame_s.c test_wmemmove_s.c test_strcasestr_s.c test_strljustify_s.c test_wmemset_s.c test_strcat_s.c test_strncat_s.c test_strcmpfld_s.c test_strncpy_s.c
|
||||
|
||||
_TLIST2 = $(addprefix $(OTDIR)/,$(_TESTFUNCS))
|
||||
TOBJ = $(patsubst %.c,%.o,$(_TLIST2))
|
||||
TCLIB =$(addprefix $(TESTDIR)/,$(_TESTFUNCS))
|
||||
|
||||
|
||||
$(OTDIR)/%.o: $(TESTDIR)/%.c $(TESTDIR)/test_private.h
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
|
||||
safestringtest: directories libsafestring.a $(TOBJ)
|
||||
$(CC) $(LDFLAGS) -static -o $@ $(TOBJ) libsafestring.a
|
||||
|
||||
|
||||
.PHONY: directories
|
||||
|
||||
directories: ${ODIR} ${OTDIR}
|
||||
|
||||
${ODIR}:
|
||||
${MKDIR_P} ${ODIR}
|
||||
|
||||
${OTDIR}:
|
||||
${MKDIR_P} ${OTDIR}
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ $(OTDIR)/*.o
|
||||
rm -f libsafestring.a
|
||||
rm -f safestringtest
|
|
@ -0,0 +1,74 @@
|
|||
/*------------------------------------------------------------------
|
||||
* abort_handler_s.c
|
||||
*
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2012 Cisco Systems
|
||||
* 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"
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* abort_handler_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_lib.h"
|
||||
* void abort_handler_s(const char *msg, void *ptr, errno_t error)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function writes a message on the standard error stream in
|
||||
* an implementation-defined format. The message shall include the
|
||||
* string pointed to by msg. The abort_handler_s function then calls
|
||||
* the abort function.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* msg Pointer to the message describing the error
|
||||
*
|
||||
* ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* Does not return to caller.
|
||||
*
|
||||
* ALSO SEE
|
||||
* ignore_handler_s()
|
||||
*
|
||||
*/
|
||||
|
||||
void abort_handler_s(const char *msg, void *ptr, errno_t error)
|
||||
{
|
||||
slprintf("ABORT CONSTRAINT HANDLER: (%u) %s\n", error,
|
||||
(msg) ? msg : "Null message");
|
||||
slabort();
|
||||
}
|
||||
EXPORT_SYMBOL(abort_handler_s)
|
|
@ -0,0 +1,72 @@
|
|||
/*------------------------------------------------------------------
|
||||
* ignore_handler_s.c
|
||||
*
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2012 Cisco Systems
|
||||
* 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"
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* ignore_handler_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_lib.h"
|
||||
* void ignore_handler_s(const char *msg, void *ptr, errno_t error)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function simply returns to the caller.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* msg Pointer to the message describing the error
|
||||
*
|
||||
* ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* Returns no value.
|
||||
*
|
||||
* ALSO SEE
|
||||
* abort_handler_s()
|
||||
*
|
||||
*/
|
||||
|
||||
void ignore_handler_s(const char *msg, void *ptr, errno_t error)
|
||||
{
|
||||
|
||||
sldebug_printf("IGNORE CONSTRAINT HANDLER: (%u) %s\n", error,
|
||||
(msg) ? msg : "Null message");
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(ignore_handler_s)
|
|
@ -0,0 +1,853 @@
|
|||
/*------------------------------------------------------------------
|
||||
* mem_primitives_lib.c - Unguarded Memory Copy Routines
|
||||
*
|
||||
* February 2005, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2005-2009 Cisco Systems
|
||||
* 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 "mem_primitives_lib.h"
|
||||
|
||||
/*
|
||||
* mem_primitives_lib.c provides unguarded memory routines
|
||||
* that are used by the safe_mem_library. These routines
|
||||
* may also be used by an application, but the application
|
||||
* is responsible for all parameter validation and alignment.
|
||||
*/
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_set - Sets memory to value
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_set(void *dest, uint32_t len, uint8_t value)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Sets len bytes starting at dest to the specified value
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest - pointer to memory that will be set to value
|
||||
*
|
||||
* len - number of bytes to be set
|
||||
*
|
||||
* value - byte value
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_set (void *dest, uint32_t len, uint8_t value)
|
||||
{
|
||||
uint8_t *dp;
|
||||
uint32_t count;
|
||||
uint32_t lcount;
|
||||
|
||||
uint32_t *lp;
|
||||
uint32_t value32;
|
||||
|
||||
count = len;
|
||||
|
||||
dp = dest;
|
||||
|
||||
value32 = value | (value << 8) | (value << 16) | (value << 24);
|
||||
|
||||
/*
|
||||
* First, do the few bytes to get uint32_t aligned.
|
||||
*/
|
||||
for (; count && ( (uintptr_t)dp & (sizeof(uint32_t)-1) ); count--) {
|
||||
*dp++ = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Then do the uint32_ts, unrolled the loop for performance
|
||||
*/
|
||||
lp = (uint32_t *)dp;
|
||||
lcount = count >> 2;
|
||||
|
||||
while (lcount != 0) {
|
||||
|
||||
switch (lcount) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32;
|
||||
*lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32;
|
||||
*lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32;
|
||||
*lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32;
|
||||
lcount -= 16;
|
||||
break;
|
||||
|
||||
case 15: *lp++ = value32;
|
||||
case 14: *lp++ = value32;
|
||||
case 13: *lp++ = value32;
|
||||
case 12: *lp++ = value32;
|
||||
case 11: *lp++ = value32;
|
||||
case 10: *lp++ = value32;
|
||||
case 9: *lp++ = value32;
|
||||
case 8: *lp++ = value32;
|
||||
|
||||
case 7: *lp++ = value32;
|
||||
case 6: *lp++ = value32;
|
||||
case 5: *lp++ = value32;
|
||||
case 4: *lp++ = value32;
|
||||
case 3: *lp++ = value32;
|
||||
case 2: *lp++ = value32;
|
||||
case 1: *lp++ = value32;
|
||||
lcount = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
|
||||
dp = (uint8_t *)lp;
|
||||
|
||||
/*
|
||||
* compute the number of remaining bytes
|
||||
*/
|
||||
count &= (sizeof(uint32_t)-1);
|
||||
|
||||
/*
|
||||
* remaining bytes
|
||||
*/
|
||||
for (; count; dp++, count--) {
|
||||
*dp = value;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_set16 - Sets memory to value
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_set16(uint16_t *dp, uint32_t len, uint16_t value)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Sets len uint16_ts starting at dest to the specified value.
|
||||
* Pointers must meet system alignment requirements.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest - pointer to memory that will be set to value
|
||||
*
|
||||
* len - number of uint16_ts to be set
|
||||
*
|
||||
* value - uint16_t value
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_set16 (uint16_t *dp, uint32_t len, uint16_t value)
|
||||
{
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = value;
|
||||
case 14: *dp++ = value;
|
||||
case 13: *dp++ = value;
|
||||
case 12: *dp++ = value;
|
||||
case 11: *dp++ = value;
|
||||
case 10: *dp++ = value;
|
||||
case 9: *dp++ = value;
|
||||
case 8: *dp++ = value;
|
||||
|
||||
case 7: *dp++ = value;
|
||||
case 6: *dp++ = value;
|
||||
case 5: *dp++ = value;
|
||||
case 4: *dp++ = value;
|
||||
case 3: *dp++ = value;
|
||||
case 2: *dp++ = value;
|
||||
case 1: *dp++ = value;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_set32 - Sets memory to the uint32_t value
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_set32(uint32_t *dp, uint32_t len, uint32_t value)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Sets len uint32_ts starting at dest to the specified value
|
||||
* Pointers must meet system alignment requirements.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest - pointer to memory that will be set to value
|
||||
*
|
||||
* len - number of uint32_ts to be set
|
||||
*
|
||||
* value - uint32_t value
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_set32 (uint32_t *dp, uint32_t len, uint32_t value)
|
||||
{
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = value;
|
||||
case 14: *dp++ = value;
|
||||
case 13: *dp++ = value;
|
||||
case 12: *dp++ = value;
|
||||
case 11: *dp++ = value;
|
||||
case 10: *dp++ = value;
|
||||
case 9: *dp++ = value;
|
||||
case 8: *dp++ = value;
|
||||
|
||||
case 7: *dp++ = value;
|
||||
case 6: *dp++ = value;
|
||||
case 5: *dp++ = value;
|
||||
case 4: *dp++ = value;
|
||||
case 3: *dp++ = value;
|
||||
case 2: *dp++ = value;
|
||||
case 1: *dp++ = value;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_move - Move (handles overlap) memory
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_move(void *dest, const void *src, uint32_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Moves at most slen bytes from src to dest, up to dmax
|
||||
* bytes. Dest may overlap with src.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest - pointer to the memory that will be replaced by src.
|
||||
*
|
||||
* src - pointer to the memory that will be copied
|
||||
* to dest
|
||||
*
|
||||
* len - maximum number bytes of src that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_move (void *dest, const void *src, uint32_t len)
|
||||
{
|
||||
|
||||
#define wsize sizeof(uint32_t)
|
||||
#define wmask (wsize - 1)
|
||||
|
||||
uint8_t *dp = dest;
|
||||
const uint8_t *sp = src;
|
||||
|
||||
uint32_t tsp;
|
||||
|
||||
/*
|
||||
* Determine if we need to copy forward or backward (overlap)
|
||||
*/
|
||||
if ((uintptr_t)dp < (uintptr_t)sp) {
|
||||
/*
|
||||
* Copy forward.
|
||||
*/
|
||||
|
||||
/*
|
||||
* get a working copy of src for bit operations
|
||||
*/
|
||||
tsp = (uintptr_t)sp;
|
||||
|
||||
/*
|
||||
* Try to align both operands. This cannot be done
|
||||
* unless the low bits match.
|
||||
*/
|
||||
if ((tsp | (uintptr_t)dp) & wmask) {
|
||||
/*
|
||||
* determine how many bytes to copy to align operands
|
||||
*/
|
||||
if ((tsp ^ (uintptr_t)dp) & wmask || len < wsize) {
|
||||
tsp = len;
|
||||
|
||||
} else {
|
||||
tsp = wsize - (tsp & wmask);
|
||||
}
|
||||
|
||||
len -= tsp;
|
||||
|
||||
/*
|
||||
* make the alignment
|
||||
*/
|
||||
do {
|
||||
*dp++ = *sp++;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now copy, then mop up any trailing bytes.
|
||||
*/
|
||||
tsp = len / wsize;
|
||||
|
||||
if (tsp > 0) {
|
||||
|
||||
do {
|
||||
*(uint32_t *)dp = *(uint32_t *)sp;
|
||||
|
||||
sp += wsize;
|
||||
dp += wsize;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy over the remaining bytes and we're done
|
||||
*/
|
||||
tsp = len & wmask;
|
||||
|
||||
if (tsp > 0) {
|
||||
do {
|
||||
*dp++ = *sp++;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
* This section is used to copy backwards, to handle any
|
||||
* overlap. The alignment requires (tps&wmask) bytes to
|
||||
* align.
|
||||
*/
|
||||
|
||||
/*
|
||||
* go to end of the memory to copy
|
||||
*/
|
||||
sp += len;
|
||||
dp += len;
|
||||
|
||||
/*
|
||||
* get a working copy of src for bit operations
|
||||
*/
|
||||
tsp = (uintptr_t)sp;
|
||||
|
||||
/*
|
||||
* Try to align both operands.
|
||||
*/
|
||||
if ((tsp | (uintptr_t)dp) & wmask) {
|
||||
|
||||
if ((tsp ^ (uintptr_t)dp) & wmask || len <= wsize) {
|
||||
tsp = len;
|
||||
} else {
|
||||
tsp &= wmask;
|
||||
}
|
||||
|
||||
len -= tsp;
|
||||
|
||||
/*
|
||||
* make the alignment
|
||||
*/
|
||||
do {
|
||||
*--dp = *--sp;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now copy in uint32_t units, then mop up any trailing bytes.
|
||||
*/
|
||||
tsp = len / wsize;
|
||||
|
||||
if (tsp > 0) {
|
||||
do {
|
||||
sp -= wsize;
|
||||
dp -= wsize;
|
||||
|
||||
*(uint32_t *)dp = *(uint32_t *)sp;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy over the remaining bytes and we're done
|
||||
*/
|
||||
tsp = len & wmask;
|
||||
if (tsp > 0) {
|
||||
tsp = len & wmask;
|
||||
do {
|
||||
*--dp = *--sp;
|
||||
} while (--tsp);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_move8 - Move (handles overlap) memory
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_move8(void *dest, const void *src, uint32_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Moves at most len uint8_ts from sp to dp.
|
||||
* The destination may overlap with source.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dp - pointer to the memory that will be replaced by sp.
|
||||
*
|
||||
* sp - pointer to the memory that will be copied
|
||||
* to dp
|
||||
*
|
||||
* len - maximum number uint8_t of sp that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dp - pointer to the memory that will be replaced by sp.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_move8 (uint8_t *dp, const uint8_t *sp, uint32_t len)
|
||||
{
|
||||
|
||||
/*
|
||||
* Determine if we need to copy forward or backward (overlap)
|
||||
*/
|
||||
if (dp < sp) {
|
||||
/*
|
||||
* Copy forward.
|
||||
*/
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = *sp++;
|
||||
case 14: *dp++ = *sp++;
|
||||
case 13: *dp++ = *sp++;
|
||||
case 12: *dp++ = *sp++;
|
||||
case 11: *dp++ = *sp++;
|
||||
case 10: *dp++ = *sp++;
|
||||
case 9: *dp++ = *sp++;
|
||||
case 8: *dp++ = *sp++;
|
||||
|
||||
case 7: *dp++ = *sp++;
|
||||
case 6: *dp++ = *sp++;
|
||||
case 5: *dp++ = *sp++;
|
||||
case 4: *dp++ = *sp++;
|
||||
case 3: *dp++ = *sp++;
|
||||
case 2: *dp++ = *sp++;
|
||||
case 1: *dp++ = *sp++;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
} else {
|
||||
/*
|
||||
* This section is used to copy backwards, to handle any
|
||||
* overlap. The alignment requires (tps&wmask) bytes to
|
||||
* align.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* go to end of the memory to copy
|
||||
*/
|
||||
sp += len;
|
||||
dp += len;
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *--dp = *--sp;
|
||||
case 14: *--dp = *--sp;
|
||||
case 13: *--dp = *--sp;
|
||||
case 12: *--dp = *--sp;
|
||||
case 11: *--dp = *--sp;
|
||||
case 10: *--dp = *--sp;
|
||||
case 9: *--dp = *--sp;
|
||||
case 8: *--dp = *--sp;
|
||||
|
||||
case 7: *--dp = *--sp;
|
||||
case 6: *--dp = *--sp;
|
||||
case 5: *--dp = *--sp;
|
||||
case 4: *--dp = *--sp;
|
||||
case 3: *--dp = *--sp;
|
||||
case 2: *--dp = *--sp;
|
||||
case 1: *--dp = *--sp;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_move16 - Move (handles overlap) memory
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_move16(void *dest, const void *src, uint32_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Moves at most len uint16_ts from sp to dp.
|
||||
* The destination may overlap with source.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dp - pointer to the memory that will be replaced by sp.
|
||||
*
|
||||
* sp - pointer to the memory that will be copied
|
||||
* to dp
|
||||
*
|
||||
* len - maximum number uint16_t of sp that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dp - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_move16 (uint16_t *dp, const uint16_t *sp, uint32_t len)
|
||||
{
|
||||
|
||||
/*
|
||||
* Determine if we need to copy forward or backward (overlap)
|
||||
*/
|
||||
if (dp < sp) {
|
||||
/*
|
||||
* Copy forward.
|
||||
*/
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = *sp++;
|
||||
case 14: *dp++ = *sp++;
|
||||
case 13: *dp++ = *sp++;
|
||||
case 12: *dp++ = *sp++;
|
||||
case 11: *dp++ = *sp++;
|
||||
case 10: *dp++ = *sp++;
|
||||
case 9: *dp++ = *sp++;
|
||||
case 8: *dp++ = *sp++;
|
||||
|
||||
case 7: *dp++ = *sp++;
|
||||
case 6: *dp++ = *sp++;
|
||||
case 5: *dp++ = *sp++;
|
||||
case 4: *dp++ = *sp++;
|
||||
case 3: *dp++ = *sp++;
|
||||
case 2: *dp++ = *sp++;
|
||||
case 1: *dp++ = *sp++;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
} else {
|
||||
/*
|
||||
* This section is used to copy backwards, to handle any
|
||||
* overlap. The alignment requires (tps&wmask) bytes to
|
||||
* align.
|
||||
*/
|
||||
|
||||
/*
|
||||
* go to end of the memory to copy
|
||||
*/
|
||||
sp += len;
|
||||
dp += len;
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *--dp = *--sp;
|
||||
case 14: *--dp = *--sp;
|
||||
case 13: *--dp = *--sp;
|
||||
case 12: *--dp = *--sp;
|
||||
case 11: *--dp = *--sp;
|
||||
case 10: *--dp = *--sp;
|
||||
case 9: *--dp = *--sp;
|
||||
case 8: *--dp = *--sp;
|
||||
|
||||
case 7: *--dp = *--sp;
|
||||
case 6: *--dp = *--sp;
|
||||
case 5: *--dp = *--sp;
|
||||
case 4: *--dp = *--sp;
|
||||
case 3: *--dp = *--sp;
|
||||
case 2: *--dp = *--sp;
|
||||
case 1: *--dp = *--sp;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_move32 - Move (handles overlap) memory
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_move32(void *dest, const void *src, uint32_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Moves at most len uint32_ts from sp to dp.
|
||||
* The destination may overlap with source.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dp - pointer to the memory that will be replaced by sp.
|
||||
*
|
||||
* sp - pointer to the memory that will be copied
|
||||
* to dp
|
||||
*
|
||||
* len - maximum number uint32_t of sp that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dp - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_move32 (uint32_t *dp, const uint32_t *sp, uint32_t len)
|
||||
{
|
||||
|
||||
/*
|
||||
* Determine if we need to copy forward or backward (overlap)
|
||||
*/
|
||||
if (dp < sp) {
|
||||
/*
|
||||
* Copy forward.
|
||||
*/
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = *sp++;
|
||||
case 14: *dp++ = *sp++;
|
||||
case 13: *dp++ = *sp++;
|
||||
case 12: *dp++ = *sp++;
|
||||
case 11: *dp++ = *sp++;
|
||||
case 10: *dp++ = *sp++;
|
||||
case 9: *dp++ = *sp++;
|
||||
case 8: *dp++ = *sp++;
|
||||
|
||||
case 7: *dp++ = *sp++;
|
||||
case 6: *dp++ = *sp++;
|
||||
case 5: *dp++ = *sp++;
|
||||
case 4: *dp++ = *sp++;
|
||||
case 3: *dp++ = *sp++;
|
||||
case 2: *dp++ = *sp++;
|
||||
case 1: *dp++ = *sp++;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
} else {
|
||||
/*
|
||||
* This section is used to copy backwards, to handle any
|
||||
* overlap.
|
||||
*/
|
||||
|
||||
/*
|
||||
* go to end of the memory to copy
|
||||
*/
|
||||
sp += len;
|
||||
dp += len;
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *--dp = *--sp;
|
||||
case 14: *--dp = *--sp;
|
||||
case 13: *--dp = *--sp;
|
||||
case 12: *--dp = *--sp;
|
||||
case 11: *--dp = *--sp;
|
||||
case 10: *--dp = *--sp;
|
||||
case 9: *--dp = *--sp;
|
||||
case 8: *--dp = *--sp;
|
||||
|
||||
case 7: *--dp = *--sp;
|
||||
case 6: *--dp = *--sp;
|
||||
case 5: *--dp = *--sp;
|
||||
case 4: *--dp = *--sp;
|
||||
case 3: *--dp = *--sp;
|
||||
case 2: *--dp = *--sp;
|
||||
case 1: *--dp = *--sp;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*------------------------------------------------------------------
|
||||
* mem_primitives_lib.h - Unguarded Memory Copy Routines
|
||||
*
|
||||
* 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __MEM_PRIMITIVES_LIB_H__
|
||||
#define __MEM_PRIMITIVES_LIB_H__
|
||||
|
||||
#include "safeclib_private.h"
|
||||
|
||||
/*
|
||||
* These are prototypes for _unguarded_ memory routines. The caller must
|
||||
* validate all parameters prior to invocation. Useful for diagnostics
|
||||
* and system initialization processing.
|
||||
*/
|
||||
|
||||
/* moves (handles overlap) memory */
|
||||
extern void
|
||||
mem_prim_move(void *dest, const void *src, uint32_t length);
|
||||
|
||||
|
||||
/* uint8_t moves (handles overlap) memory */
|
||||
extern void
|
||||
mem_prim_move8(uint8_t *dest, const uint8_t *src, uint32_t length);
|
||||
|
||||
/* uint16_t moves (handles overlap) memory */
|
||||
extern void
|
||||
mem_prim_move16(uint16_t *dest, const uint16_t *src, uint32_t length);
|
||||
|
||||
/* uint32_t moves (handles overlap) memory */
|
||||
extern void
|
||||
mem_prim_move32(uint32_t *dest, const uint32_t *src, uint32_t length);
|
||||
|
||||
|
||||
/* set bytes */
|
||||
extern void
|
||||
mem_prim_set(void *dest, uint32_t dmax, uint8_t value);
|
||||
|
||||
/* set uint16_ts */
|
||||
extern void
|
||||
mem_prim_set16(uint16_t *dest, uint32_t dmax, uint16_t value);
|
||||
|
||||
/* set uint32_ts */
|
||||
extern void
|
||||
mem_prim_set32(uint32_t *dest, uint32_t dmax, uint32_t value);
|
||||
|
||||
|
||||
#endif /* __MEM_PRIMITIVES_LIB_H__ */
|
|
@ -0,0 +1,173 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memcmp16_s.c - Compares memory
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memcmp16_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memcmp16_s(const uint16_t *dest, rsize_t dmax,
|
||||
* const uint16_t *src, rsize_t smax, int *diff)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Compares memory until they differ, and their difference is
|
||||
* returned in diff. If the block of memory is the same, diff=0.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory to compare against
|
||||
*
|
||||
* dmax maximum length of dest, in uint16_t
|
||||
*
|
||||
* src pointer to the source memory to compare with dest
|
||||
*
|
||||
* smax maximum length of src, in uint16_t
|
||||
*
|
||||
* *diff pointer to the diff which is an integer greater
|
||||
* than, equal to or less than zero according to
|
||||
* whether the object pointed to by dest is
|
||||
* greater than, equal to or less than the object
|
||||
* pointed to by src.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM.
|
||||
* smax shall not be greater than dmax.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memcmp_s(), memcmp32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memcmp16_s (const uint16_t *dest, rsize_t dmax,
|
||||
const uint16_t *src, rsize_t smax, int *diff)
|
||||
{
|
||||
|
||||
const uint16_t *dp;
|
||||
const uint16_t *sp;
|
||||
|
||||
dp = dest;
|
||||
sp = src;
|
||||
|
||||
/*
|
||||
* must be able to return the diff
|
||||
*/
|
||||
if (diff == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcmp16_s: diff is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
*diff = -1; /* default diff */
|
||||
|
||||
if (dp == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcmp16_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (sp == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcmp16_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcmp16_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM16) {
|
||||
invoke_safe_mem_constraint_handler("memcmp16_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (smax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcmp16_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
invoke_safe_mem_constraint_handler("memcmp16_s: smax exceeds dmax",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
/*
|
||||
* no need to compare the same memory
|
||||
*/
|
||||
if (dp == sp) {
|
||||
*diff = 0;
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
|
||||
/*
|
||||
* now compare sp to dp
|
||||
*/
|
||||
*diff = 0;
|
||||
while (dmax != 0 && smax != 0) {
|
||||
if (*dp != *sp) {
|
||||
*diff = *dp - *sp;
|
||||
break;
|
||||
}
|
||||
|
||||
dmax--;
|
||||
smax--;
|
||||
|
||||
dp++;
|
||||
sp++;
|
||||
}
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memcmp16_s)
|
|
@ -0,0 +1,167 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memcmp32_s.c - Compares memory
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memcmp32_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memcmp32_s(const uint32_t *dest, rsize_t dmax,
|
||||
* const uint32_t *src, rsize_t smax, int *diff)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Compares memory until they differ, and their difference is
|
||||
* returned in diff. If the block of memory is the same, diff=0.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory to compare against
|
||||
*
|
||||
* dmax maximum length of dest, in uint32_t
|
||||
*
|
||||
* src pointer to the source memory to compare with dest
|
||||
*
|
||||
* smax maximum length of src, in uint32_t
|
||||
*
|
||||
* *diff pointer to the diff which is an integer greater
|
||||
* than, equal to or less than zero according to
|
||||
* whether the object pointed to by dest is
|
||||
* greater than, equal to or less than the object
|
||||
* pointed to by src.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM.
|
||||
* smax shall not be greater than dmax.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memcmp_s(), memcmp16_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memcmp32_s (const uint32_t *dest, rsize_t dmax,
|
||||
const uint32_t *src, rsize_t smax, int *diff)
|
||||
{
|
||||
/*
|
||||
* must be able to return the diff
|
||||
*/
|
||||
if (diff == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcmp32_s: diff is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
*diff = -1; /* default diff */
|
||||
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcmp32_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcmp32_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcmp32_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM32) {
|
||||
invoke_safe_mem_constraint_handler("memcmp32_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (smax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcmp32_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
invoke_safe_mem_constraint_handler("memcmp32_s: smax exceeds dmax",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
/*
|
||||
* no need to compare the same memory
|
||||
*/
|
||||
if (dest == src) {
|
||||
*diff = 0;
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
|
||||
/*
|
||||
* now compare src to dest
|
||||
*/
|
||||
*diff = 0;
|
||||
while (dmax != 0 && smax != 0) {
|
||||
if (*dest != *src) {
|
||||
*diff = *dest - *src;
|
||||
break;
|
||||
}
|
||||
|
||||
dmax--;
|
||||
smax--;
|
||||
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memcmp32_s)
|
|
@ -0,0 +1,174 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memcmp_s.c - Compares memory
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memcmp_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memcmp_s(const void *dest, rsize_t dmax,
|
||||
* const void *src, rsize_t smax, int *diff)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Compares memory until they differ, and their difference is
|
||||
* returned in diff. If the block of memory is the same, diff=0.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory to compare against
|
||||
*
|
||||
* dmax maximum length of dest, in bytess
|
||||
*
|
||||
* src pointer to the source memory to compare with dest
|
||||
*
|
||||
* smax length of the source memory block
|
||||
*
|
||||
* *diff pointer to the diff which is an integer greater
|
||||
* than, equal to or less than zero according to
|
||||
* whether the object pointed to by dest is
|
||||
* greater than, equal to or less than the object
|
||||
* pointed to by src.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM.
|
||||
* smax shall not be greater than dmax.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memcmp16_s(), memcmp32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memcmp_s (const void *dest, rsize_t dmax,
|
||||
const void *src, rsize_t smax, int *diff)
|
||||
{
|
||||
const uint8_t *dp;
|
||||
const uint8_t *sp;
|
||||
|
||||
dp = dest;
|
||||
sp = src;
|
||||
|
||||
/*
|
||||
* must be able to return the diff
|
||||
*/
|
||||
if (diff == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcmp_s: diff is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
*diff = -1; /* default diff */
|
||||
|
||||
if (dp == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcmp_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (sp == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcmp_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcmp_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM) {
|
||||
invoke_safe_mem_constraint_handler("memcmp_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (smax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcmp_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
invoke_safe_mem_constraint_handler("memcmp_s: smax exceeds dmax",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
/*
|
||||
* no need to compare the same memory
|
||||
*/
|
||||
if (dp == sp) {
|
||||
*diff = 0;
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
|
||||
/*
|
||||
* now compare sp to dp
|
||||
*/
|
||||
*diff = 0;
|
||||
while (dmax > 0 && smax > 0) {
|
||||
if (*dp != *sp) {
|
||||
/*** *diff = *dp - *sp; ***/
|
||||
*diff = *dp < *sp ? -1 : 1;
|
||||
break;
|
||||
}
|
||||
|
||||
dmax--;
|
||||
smax--;
|
||||
|
||||
dp++;
|
||||
sp++;
|
||||
}
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memcmp_s)
|
|
@ -0,0 +1,151 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memcpy16_s
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memcpy16_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memcpy16_s(uint16_t *dest, rsize_t dmax,
|
||||
* const uint16_t *src, rsize_t smax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function copies at most smax uint16_ts from src to dest, up to
|
||||
* dmax.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory that will be replaced by src.
|
||||
*
|
||||
* dmax maximum length of the resulting dest
|
||||
*
|
||||
* src pointer to the memory that will be copied to dest
|
||||
*
|
||||
* smax maximum number uint16_t of src to copy
|
||||
*
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be 0.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM16.
|
||||
* smax shall not be greater than dmax.
|
||||
* Copying shall not take place between objects that overlap.
|
||||
* If there is a runtime-constraint violation, the memcpy_s function stores
|
||||
* zeros in the first dmax bytes of the object pointed to by dest
|
||||
* if dest is not a null pointer and smax is valid.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESOVRLP source memory overlaps destination
|
||||
*
|
||||
* ALSO SEE
|
||||
* memcpy_s(), memcpy32_s(), memmove_s(), memmove16_s(), memmove32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memcpy16_s (uint16_t *dest, rsize_t dmax, const uint16_t *src, rsize_t smax)
|
||||
{
|
||||
if (dest == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcpy16_s: dest is NULL",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcpy16_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM16) {
|
||||
invoke_safe_mem_constraint_handler("memcpy16_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (smax == 0) {
|
||||
mem_prim_set16(dest, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy16_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
mem_prim_set16(dest, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy16_s: smax exceeds dmax",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
mem_prim_set16(dest, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy16_s: src is NULL",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
/*
|
||||
* overlap is undefined behavior, do not allow
|
||||
*/
|
||||
if( ((dest > src) && (dest < (src+smax))) ||
|
||||
((src > dest) && (src < (dest+dmax))) ) {
|
||||
mem_prim_set16(dest, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy16_s: overlap undefined",
|
||||
NULL, ESOVRLP);
|
||||
return (RCNEGATE(ESOVRLP));
|
||||
}
|
||||
|
||||
/*
|
||||
* now perform the copy
|
||||
*/
|
||||
mem_prim_move16(dest, src, smax);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memcpy16_s)
|
|
@ -0,0 +1,150 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memcpy32_s
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memcpy32_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memcpy32_s(uint32_t *dest, rsize_t dmax,
|
||||
* const uint32_t *src, rsize_t smax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function copies at most smax uint32_ts from src to dest, up to
|
||||
* dmax.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory that will be replaced by src.
|
||||
*
|
||||
* dmax maximum length of the resulting dest
|
||||
*
|
||||
* src pointer to the memory that will be copied to dest
|
||||
*
|
||||
* smax maximum number uint32_t of src to copy
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be 0.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM32.
|
||||
* smax shall not be greater than dmax.
|
||||
* Copying shall not take place between objects that overlap.
|
||||
* If there is a runtime-constraint violation, the memcpy_s function stores
|
||||
* zeros in the first dmax bytes of the object pointed to by dest
|
||||
* if dest is not a null pointer and smax is valid.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK operation sucessful
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL length was zero
|
||||
* ESLEMAX length exceeds max
|
||||
* ESOVRLP source memory overlaps destination
|
||||
*
|
||||
* ALSO SEE
|
||||
* memcpy_s(), memcpy16_s(), memmove_s(), memmove16_s(), memmove32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memcpy32_s (uint32_t *dest, rsize_t dmax, const uint32_t *src, rsize_t smax)
|
||||
{
|
||||
if (dest == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcpy32_s: dest is NULL",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcpy32_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM32) {
|
||||
invoke_safe_mem_constraint_handler("memcpy32_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (smax == 0) {
|
||||
mem_prim_set32(dest, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy32_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
mem_prim_set32(dest, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy32_s: smax exceeds dmax",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
mem_prim_set32(dest, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy32_s: src is NULL",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
/*
|
||||
* overlap is undefined behavior, do not allow
|
||||
*/
|
||||
if( ((dest > src) && (dest < (src+smax))) ||
|
||||
((src > dest) && (src < (dest+dmax))) ) {
|
||||
mem_prim_set32(dest, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy32_s: overlap undefined",
|
||||
NULL, ESOVRLP);
|
||||
return (RCNEGATE(ESOVRLP));
|
||||
}
|
||||
|
||||
/*
|
||||
* now perform the copy
|
||||
*/
|
||||
mem_prim_move32(dest, src, smax);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memcpy32_s)
|
|
@ -0,0 +1,163 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memcpy_s
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memcpy_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memcpy_s(void *dest, rsize_t dmax, const void *src, rsize_t smax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function copies at most smax bytes from src to dest, up to
|
||||
* dmax. The size values are unsigned values.
|
||||
*
|
||||
* AR: Dave - verify ISO spec requires unsigned
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory that will be replaced by src.
|
||||
*
|
||||
* dmax maximum length of the resulting dest
|
||||
*
|
||||
* src pointer to the memory that will be copied to dest
|
||||
*
|
||||
* smax maximum number bytes of src to copy
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM.
|
||||
* smax shall not be greater than dmax.
|
||||
* Copying shall not take place between regions that overlap.
|
||||
* If there is a runtime-constraint violation, the memcpy_s function
|
||||
* stores zeros in the first dmax bytes of the region pointed to
|
||||
* by dest if dest is not a null pointer and smax is valid.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESOVRLP source memory overlaps destination
|
||||
*
|
||||
* ALSO SEE
|
||||
* memcpy16_s(), memcpy32_s(), memmove_s(), memmove16_s(),
|
||||
* memmove32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memcpy_s (void *dest, rsize_t dmax, const void *src, rsize_t smax)
|
||||
{
|
||||
uint8_t *dp;
|
||||
const uint8_t *sp;
|
||||
|
||||
dp = dest;
|
||||
sp = src;
|
||||
|
||||
if (dp == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: dest is NULL",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM) {
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
// AR: This is not a requirement according to the ISO spec - Change?
|
||||
// AR: documentation needed on use of the error handlers -
|
||||
// AR: default err handler should output to stderr on DEBUG
|
||||
// AR: update docs to define return RCNEGATE of the error number
|
||||
if (smax == 0) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: smax exceeds dmax",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
if (sp == NULL) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: src is NULL",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* overlap is undefined behavior, do not allow
|
||||
*/
|
||||
if( ((dp > sp) && (dp < (sp+smax))) ||
|
||||
((sp > dp) && (sp < (dp+dmax))) ) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: overlap undefined",
|
||||
NULL, ESOVRLP);
|
||||
return RCNEGATE(ESOVRLP);
|
||||
}
|
||||
|
||||
/*
|
||||
* now perform the copy
|
||||
*/
|
||||
mem_prim_move(dp, sp, smax);
|
||||
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
EXPORT_SYMBOL(memcpy_s)
|
|
@ -0,0 +1,151 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memmove16_s.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memmove16_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memmove16_s(uint16_t *dest, rsize_t dmax,
|
||||
* const uint16_t *src, rsize_t smax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The memmove16_s function copies smax uint16_t from the region
|
||||
* pointed to by src into the region pointed to by dest. This
|
||||
* copying takes place as if the smax uint16_t from the region
|
||||
* pointed to by src are first copied into a temporary array of
|
||||
* smax uint16_t that does not overlap the regions pointed to
|
||||
* by dest or src, and then the smax uint16_t from the temporary
|
||||
* array are copied into the region pointed to by dest.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to the memory that will be replaced by src.
|
||||
*
|
||||
* dmax maximum length of the resulting dest, in uint16_t
|
||||
*
|
||||
* src pointer to the memory that will be copied
|
||||
* to dest
|
||||
*
|
||||
* smax maximum number uint16_t of src that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be 0.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM.
|
||||
* smax shall not be greater than dmax.
|
||||
* If there is a runtime-constraint violation, the memmove_s function
|
||||
* stores zeros in the first dmax characters of the regionpointed to
|
||||
* by dest if dest is not a null pointer and dmax is not greater
|
||||
* than RSIZE_MAX_MEM.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memmove_s(), memmove32_s(), memcpy_s(), memcpy16_s() memcpy32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memmove16_s (uint16_t *dest, rsize_t dmax, const uint16_t *src, rsize_t smax)
|
||||
{
|
||||
uint16_t *dp;
|
||||
const uint16_t *sp;
|
||||
|
||||
dp= dest;
|
||||
sp = src;
|
||||
|
||||
if (dp == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memove16_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memove16_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM16) {
|
||||
invoke_safe_mem_constraint_handler("memove16_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (smax == 0) {
|
||||
mem_prim_set16(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memove16_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
mem_prim_set16(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memove16_s: smax exceeds dmax",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (sp == NULL) {
|
||||
mem_prim_set16(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memove16_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* now perform the copy
|
||||
*/
|
||||
mem_prim_move16(dp, sp, smax);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memmove16_s)
|
|
@ -0,0 +1,150 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memmove32_s.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memmove32_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memmove32_s(uint32_t *dest, rsize_t dmax,
|
||||
* const uint32_t *src, rsize_t smax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The memmove32_s function copies smax uint32_ts from the region
|
||||
* pointed to by src into the region pointed to by dest. This
|
||||
* copying takes place as if the smax uint32_ts from the region
|
||||
* pointed to by src are first copied into a temporary array of
|
||||
* smax uint32_ts that does not overlap the regions pointed to
|
||||
* by dest or src, and then the smax uint32_ts from the temporary
|
||||
* array are copied into the region pointed to by dest.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to the memory that will be replaced by src.
|
||||
*
|
||||
* dmax maximum length of the resulting dest, in uint32_t
|
||||
*
|
||||
* src pointer to the memory that will be copied
|
||||
* to dest
|
||||
*
|
||||
* smax maximum number uint32_t of src that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be 0.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM.
|
||||
* smax shall not be greater than dmax.
|
||||
* If there is a runtime-constraint violation, the memmove_s function
|
||||
* stores zeros in the first dmax characters of the regionpointed to
|
||||
* by dest if dest is not a null pointer and dmax is not greater
|
||||
* than RSIZE_MAX_MEM.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memmove_s(), memmove16_s(), memcpy_s(), memcpy16_s() memcpy32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memmove32_s (uint32_t *dest, rsize_t dmax, const uint32_t *src, rsize_t smax)
|
||||
{
|
||||
uint32_t *dp;
|
||||
const uint32_t *sp;
|
||||
|
||||
dp= dest;
|
||||
sp = src;
|
||||
|
||||
if (dp == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memove32_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memove32_s: dest is zero",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM32) {
|
||||
invoke_safe_mem_constraint_handler("memove32_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (smax == 0) {
|
||||
mem_prim_set32(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memove32_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
mem_prim_set32(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memove32_s: smax exceeds dmax",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (sp == NULL) {
|
||||
mem_prim_set32(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memove32_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
/*
|
||||
* now perform the copy
|
||||
*/
|
||||
mem_prim_move32(dp, sp, smax);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memmove32_s)
|
|
@ -0,0 +1,149 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memmove_s.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memmove_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memmove_s(void *dest, rsize_t dmax,
|
||||
* const void *src, rsize_t smax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The memmove_s function copies smax bytes from the region pointed
|
||||
* to by src into the region pointed to by dest. This copying takes place
|
||||
* as if the smax bytes from the region pointed to by src are first copied
|
||||
* into a temporary array of smax bytes that does not overlap the region
|
||||
* pointed to by dest or src, and then the smax bytes from the temporary
|
||||
* array are copied into the object region to by dest.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to the memory that will be replaced by src.
|
||||
*
|
||||
* dmax maximum length of the resulting dest, in bytes
|
||||
*
|
||||
* src pointer to the memory that will be copied
|
||||
* to dest
|
||||
*
|
||||
* smax maximum number bytes of src that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be 0.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM.
|
||||
* smax shall not be greater than dmax.
|
||||
* If there is a runtime-constraint violation, the memmove_s function
|
||||
* stores zeros in the first dmax characters of the regionpointed to
|
||||
* by dest if dest is not a null pointer and dmax is not greater
|
||||
* than RSIZE_MAX_MEM.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memmove16_s(), memmove32_s(), memcpy_s(), memcpy16_s() memcpy32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memmove_s (void *dest, rsize_t dmax, const void *src, rsize_t smax)
|
||||
{
|
||||
uint8_t *dp;
|
||||
const uint8_t *sp;
|
||||
|
||||
dp= dest;
|
||||
sp = src;
|
||||
|
||||
if (dp == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memmove_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memmove_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM) {
|
||||
invoke_safe_mem_constraint_handler("memmove_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (smax == 0) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memmove_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memmove_s: smax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
if (sp == NULL) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memmove_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
/*
|
||||
* now perform the copy
|
||||
*/
|
||||
mem_prim_move(dp, sp, smax);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memmove_s)
|
|
@ -0,0 +1,105 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memset16_s
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memset16_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memset16_s(uint16_t *dest, rsize_t len, uint16_t value)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Sets len uint16_t starting at dest to the specified value.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory that will be set to the value
|
||||
*
|
||||
* len number of uint16_t to be set
|
||||
*
|
||||
* value uint16_t value to be written
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* len shall not be 0 nor greater than RSIZE_MAX_MEM16.
|
||||
* If there is a runtime constraint, the operation is not performed.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memset_s(), memset32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memset16_s (uint16_t *dest, rsize_t len, uint16_t value)
|
||||
{
|
||||
if (dest == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memset16_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
invoke_safe_mem_constraint_handler("memset16_s: len is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (len > RSIZE_MAX_MEM16) {
|
||||
invoke_safe_mem_constraint_handler("memset16_s: len exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
mem_prim_set16(dest, len, value);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memset16_s)
|
|
@ -0,0 +1,105 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memset32_s
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memset32_s - Sets a block of memory to value
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memset32_s(uint32_t *dest, rsize_t len, uint32_t value)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Sets len uint32_t starting at dest to the specified value.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory that will be set to the value
|
||||
*
|
||||
* len number of uint32_t to be set
|
||||
*
|
||||
* value uint32_t value to be written
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* len shall not be 0 nor greater than RSIZE_MAX_MEM32.
|
||||
* If there is a runtime constraint, the operation is not performed.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memset_s(), memset16_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memset32_s (uint32_t *dest, rsize_t len, uint32_t value)
|
||||
{
|
||||
if (dest == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memset32_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
invoke_safe_mem_constraint_handler("memset32_s: len is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (len > RSIZE_MAX_MEM32) {
|
||||
invoke_safe_mem_constraint_handler("memset32_s: len exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
mem_prim_set32(dest, len, value);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memset32_s)
|
|
@ -0,0 +1,105 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memset_s
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memset_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memset_s(void *dest, rsize_t len, uint8_t value)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Sets len bytes starting at dest to the specified value.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory that will be set to the value
|
||||
*
|
||||
* len number of bytes to be set
|
||||
*
|
||||
* value byte value
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* len shall not be 0 nor greater than RSIZE_MAX_MEM.
|
||||
* If there is a runtime constraint, the operation is not performed.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memset16_s(), memset32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memset_s (void *dest, rsize_t len, uint8_t value)
|
||||
{
|
||||
if (dest == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memset_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
invoke_safe_mem_constraint_handler("memset_s: len is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (len > RSIZE_MAX_MEM) {
|
||||
invoke_safe_mem_constraint_handler("memset_s: len exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
mem_prim_set(dest, len, value);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memset_s)
|
|
@ -0,0 +1,107 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memzero16_s - zeros memory
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memzero16_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memzero16_s(uint16_t *dest, rsize_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Zeros len uint16_ts starting at dest.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory to be zeroed.
|
||||
*
|
||||
* len number of uint16_ts to be zeroed
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* len shall not be 0 nor greater than RSIZE_MAX_MEM16.
|
||||
* If there is a runtime constraint, the operation is not performed.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memzero_s(), memzero32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memzero16_s (uint16_t *dest, rsize_t len)
|
||||
{
|
||||
if (dest == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memzero16_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
invoke_safe_mem_constraint_handler("memzero16_s: len is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (len > RSIZE_MAX_MEM16) {
|
||||
invoke_safe_mem_constraint_handler("memzero16_s: len exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
/*
|
||||
* mem_prim_set16(dest, len, 0xDEAD);
|
||||
* mem_prim_set16(dest, len, 0xBEEF);
|
||||
*/
|
||||
mem_prim_set16(dest, len, 0);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memzero16_s)
|
|
@ -0,0 +1,108 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memzero32_s - zeros memory
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memzero32_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memzero32_s(uint32_t *dest, rsize_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Zeros len uint32_ts starting at dest.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory to be zeroed.
|
||||
*
|
||||
* len number of uint32_ts to be zeroed
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* len shall not be 0 nor greater than RSIZE_MAX_MEM32.
|
||||
* If there is a runtime constraint, the operation is not performed.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memzero_s(), memzero16_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memzero32_s (uint32_t *dest, rsize_t len)
|
||||
{
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memzero32_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
invoke_safe_mem_constraint_handler("memzero32_s: len is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (len > RSIZE_MAX_MEM32) {
|
||||
invoke_safe_mem_constraint_handler("memzero32_s: len exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
/*
|
||||
* mem_prim_set32(dest, len, 0xDEADBEEF);
|
||||
* mem_prim_set32(dest, len, 0xBA5EBA11);
|
||||
*/
|
||||
mem_prim_set32(dest, len, 0);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memzero32_s)
|
|
@ -0,0 +1,107 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memzero_s - zeros memory
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memzero_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memzero_s(void *dest, rsize_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Zeros len bytes starting at dest.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory to be zeroed.
|
||||
*
|
||||
* len number of bytes to be zeroed
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* len shall not be 0 nor greater than RSIZE_MAX_MEM.
|
||||
* If there is a runtime constraint, the operation is not performed.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* memzero16_s(), memzero32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memzero_s (void *dest, rsize_t len)
|
||||
{
|
||||
if (dest == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memzero_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (RCNEGATE(ESNULLP));
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
invoke_safe_mem_constraint_handler("memzero_s: len is 0",
|
||||
NULL, ESZEROL);
|
||||
return (RCNEGATE(ESZEROL));
|
||||
}
|
||||
|
||||
if (len > RSIZE_MAX_MEM) {
|
||||
invoke_safe_mem_constraint_handler("memzero_s: len exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (RCNEGATE(ESLEMAX));
|
||||
}
|
||||
|
||||
/*
|
||||
* mem_prim_set(dest, len, 0xA5);
|
||||
* mem_prim_set(dest, len, 0x5A);
|
||||
*/
|
||||
mem_prim_set(dest, len, 0);
|
||||
|
||||
return (RCNEGATE(EOK));
|
||||
}
|
||||
EXPORT_SYMBOL(memzero_s)
|
|
@ -0,0 +1,142 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_mem_constraint.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2008-2012 Cisco Systems
|
||||
* 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_mem_constraint.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
static constraint_handler_t mem_handler = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* set_mem_constraint_handler_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* constraint_handler_t
|
||||
* set_mem_constraint_handler_straint_handler_t handler)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The set_mem_constraint_handler_s function sets the runtime-constraint
|
||||
* handler to be handler. The runtime-constraint handler is the function to
|
||||
* be called when a library function detects a runtime-constraint
|
||||
* order:
|
||||
* 1. A pointer to a character string describing the
|
||||
* runtime-constraint violation.
|
||||
* 2. A null pointer or a pointer to an implementation defined
|
||||
* object.
|
||||
* 3. If the function calling the handler has a return type declared
|
||||
* as errno_t, the return value of the function is passed.
|
||||
* Otherwise, a positive value of type errno_t is passed.
|
||||
* The implementation has a default constraint handler that is used if no
|
||||
* calls to the set_constraint_handler_s function have been made. The
|
||||
* behavior of the default handler is implementation-defined, and it may
|
||||
* cause the program to exit or abort. If the handler argument to
|
||||
* set_constraint_handler_s is a null pointer, the implementation default
|
||||
* handler becomes the current constraint handler.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* *msg Pointer to the message describing the error
|
||||
*
|
||||
* *ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
* ALSO SEE
|
||||
* set_str_constraint_handler_s()
|
||||
*/
|
||||
constraint_handler_t
|
||||
set_mem_constraint_handler_s (constraint_handler_t handler)
|
||||
{
|
||||
constraint_handler_t prev_handler = mem_handler;
|
||||
if (NULL == handler) {
|
||||
mem_handler = sl_default_handler;
|
||||
} else {
|
||||
mem_handler = handler;
|
||||
}
|
||||
return prev_handler;
|
||||
}
|
||||
EXPORT_SYMBOL(set_mem_constraint_handler_s)
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* invoke_safe_mem_constraint_handler
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_constraint.h"
|
||||
* void
|
||||
* invoke_safe_mem_constraint_handler(const char *msg,
|
||||
* void *ptr,
|
||||
* errno_t error)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Invokes the currently set constraint handler or the default.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* *msg Pointer to the message describing the error
|
||||
*
|
||||
* *ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
invoke_safe_mem_constraint_handler (const char *msg,
|
||||
void *ptr,
|
||||
errno_t error)
|
||||
{
|
||||
if (NULL != mem_handler) {
|
||||
mem_handler(msg, ptr, error);
|
||||
} else {
|
||||
sl_default_handler(msg, ptr, error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_mem_constraint.h
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008, 2009 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_MEM_CONSTRAINT_H__
|
||||
#define __SAFE_MEM_CONSTRAINT_H__
|
||||
|
||||
#include "safeclib_private.h"
|
||||
|
||||
/*
|
||||
* Function used by the libraries to invoke the registered
|
||||
* runtime-constraint handler. Always needed.
|
||||
*/
|
||||
extern void invoke_safe_mem_constraint_handler(
|
||||
const char *msg,
|
||||
void *ptr,
|
||||
errno_t error);
|
||||
|
||||
#endif /* __SAFE_MEM_CONSTRAINT_H__ */
|
|
@ -0,0 +1,146 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_str_constraint.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2008, 2009, 2012 Cisco Systems
|
||||
* 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"
|
||||
|
||||
|
||||
static constraint_handler_t str_handler = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* set_str_constraint_handler_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* constraint_handler_t
|
||||
* set_str_constraint_handler_s(constraint_handler_t handler)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The set_str_constraint_handler_s function sets the runtime-constraint
|
||||
* handler to be handler. The runtime-constraint handler is the function to
|
||||
* be called when a library function detects a runtime-constraint
|
||||
* violation. Only the most recent handler registered with
|
||||
* set_str_constraint_handler_s is called when a runtime-constraint
|
||||
* violation occurs.
|
||||
* When the handler is called, it is passed the following arguments in
|
||||
* the following order:
|
||||
* 1. A pointer to a character string describing the
|
||||
* runtime-constraint violation.
|
||||
* 2. A null pointer or a pointer to an implementation defined
|
||||
* object.
|
||||
* 3. If the function calling the handler has a return type declared
|
||||
* as errno_t, the return value of the function is passed.
|
||||
* Otherwise, a positive value of type errno_t is passed.
|
||||
* The implementation has a default constraint handler that is used if no
|
||||
* calls to the set_constraint_handler_s function have been made. The
|
||||
* behavior of the default handler is implementation-defined, and it may
|
||||
* cause the program to exit or abort. If the handler argument to
|
||||
* set_constraint_handler_s is a null pointer, the implementation default
|
||||
* handler becomes the current constraint handler.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* *msg Pointer to the message describing the error
|
||||
*
|
||||
* *ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
* ALSO SEE
|
||||
* set_str_constraint_handler_s()
|
||||
*/
|
||||
constraint_handler_t
|
||||
set_str_constraint_handler_s (constraint_handler_t handler)
|
||||
{
|
||||
constraint_handler_t prev_handler = str_handler;
|
||||
if (NULL == handler) {
|
||||
str_handler = sl_default_handler;
|
||||
} else {
|
||||
str_handler = handler;
|
||||
}
|
||||
return prev_handler;
|
||||
}
|
||||
EXPORT_SYMBOL(set_str_constraint_handler_s)
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* invoke_safe_str_constraint_handler
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_constraint.h"
|
||||
* void
|
||||
* invoke_safe_str_constraint_handler (const char *msg,
|
||||
* void *ptr,
|
||||
* errno_t error)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Invokes the currently set constraint handler or the default.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* *msg Pointer to the message describing the error
|
||||
*
|
||||
* *ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
invoke_safe_str_constraint_handler (const char *msg,
|
||||
void *ptr,
|
||||
errno_t error)
|
||||
{
|
||||
if (NULL != str_handler) {
|
||||
str_handler(msg, ptr, error);
|
||||
} else {
|
||||
sl_default_handler(msg, ptr, error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_str_constraint.h
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_STR_CONSTRAINT_H__
|
||||
#define __SAFE_STR_CONSTRAINT_H__
|
||||
|
||||
#include "safeclib_private.h"
|
||||
|
||||
/*
|
||||
* Function used by the libraries to invoke the registered
|
||||
* runtime-constraint handler. Always needed.
|
||||
*/
|
||||
extern void invoke_safe_str_constraint_handler(
|
||||
const char *msg,
|
||||
void *ptr,
|
||||
errno_t error);
|
||||
|
||||
|
||||
/*
|
||||
* Safe C Lib internal string routine to consolidate error handling
|
||||
*/
|
||||
static inline void handle_error(char *orig_dest, rsize_t orig_dmax,
|
||||
char *err_msg, errno_t err_code)
|
||||
{
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null string to eliminate partial copy */
|
||||
while (orig_dmax) { *orig_dest = '\0'; orig_dmax--; orig_dest++; }
|
||||
#else
|
||||
*orig_dest = '\0';
|
||||
#endif
|
||||
|
||||
invoke_safe_str_constraint_handler(err_msg, NULL, err_code);
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void handle_wc_error(wchar_t *orig_dest, rsize_t orig_dmax,
|
||||
char *err_msg, errno_t err_code)
|
||||
{
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null string to eliminate partial copy */
|
||||
while (orig_dmax) { *orig_dest = L'\0'; orig_dmax--; orig_dest++; }
|
||||
#else
|
||||
*orig_dest = L'\0';
|
||||
#endif
|
||||
|
||||
invoke_safe_str_constraint_handler(err_msg, NULL, err_code);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* __SAFE_STR_CONSTRAINT_H__ */
|
|
@ -0,0 +1,93 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safeclib_private.h - Internal library references
|
||||
*
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2012, 2013 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.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFECLIB_PRIVATE_H__
|
||||
#define __SAFECLIB_PRIVATE_H__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* linux kernel environment */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#define RCNEGATE(x) ( -(x) )
|
||||
|
||||
#define slprintf(...) printk(KERN_EMERG __VA_ARGS__)
|
||||
#define slabort()
|
||||
#ifdef DEBUG
|
||||
#define sldebug_printf(...) printk(KERN_DEBUG __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#else /* !__KERNEL__ */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef STDC_HEADERS
|
||||
# include <ctype.h>
|
||||
# include <stdlib.h>
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#define EXPORT_SYMBOL(sym)
|
||||
#define RCNEGATE(x) (x)
|
||||
|
||||
#define slprintf(...) fprintf(stderr, __VA_ARGS__)
|
||||
#define slabort() abort()
|
||||
#ifdef DEBUG
|
||||
#define sldebug_printf(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#ifndef sldebug_printf
|
||||
#define sldebug_printf(...)
|
||||
#endif
|
||||
|
||||
#include "safe_lib.h"
|
||||
|
||||
#endif /* __SAFECLIB_PRIVATE_H__ */
|
|
@ -0,0 +1,329 @@
|
|||
/*------------------------------------------------------------------
|
||||
* snprintf_support.c
|
||||
*
|
||||
* August 2014, D Wheeler
|
||||
*
|
||||
* Copyright (c) 2014 by Intel Corp
|
||||
* 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"
|
||||
#include "snprintf_s.h"
|
||||
|
||||
#define FMT_CHAR 'c'
|
||||
#define FMT_WCHAR 'C'
|
||||
#define FMT_SHORT 'h'
|
||||
#define FMT_INT 'd'
|
||||
#define FMT_LONG 'l'
|
||||
#define FMT_STRING 's'
|
||||
#define FMT_WSTRING 'S'
|
||||
#define FMT_DOUBLE 'g'
|
||||
#define FMT_LDOUBLE 'G'
|
||||
#define FMT_VOID 'p'
|
||||
#define FMT_PCHAR '1'
|
||||
#define FMT_PSHORT '2'
|
||||
#define FMT_PINT '3'
|
||||
#define FMT_PLONG '4'
|
||||
|
||||
|
||||
|
||||
#define MAX_FORMAT_ELEMENTS 16
|
||||
|
||||
#define CHK_FORMAT(X,Y) (((X)==(Y))?1:0)
|
||||
|
||||
|
||||
unsigned int
|
||||
parse_format(const char *format, char pformatList[], unsigned int maxFormats)
|
||||
{
|
||||
unsigned int numFormats = 0;
|
||||
unsigned int index = 0;
|
||||
unsigned int start = 0;
|
||||
char lmod = 0;
|
||||
|
||||
while (index < RSIZE_MAX_STR && format[index] != '\0' && numFormats < maxFormats)
|
||||
{
|
||||
if (format[index] == '%') {
|
||||
start = index; // remember where the format string started
|
||||
// Check for flags
|
||||
switch( format[++index]) {
|
||||
case '\0': continue; // skip - end of format string
|
||||
case '%' : continue; // skip - actually a percent character
|
||||
case '#' : // convert to alternate form
|
||||
case '0' : // zero pad
|
||||
case '-' : // left adjust
|
||||
case ' ' : // pad with spaces
|
||||
case '+' : // force a sign be used
|
||||
index++; // skip the flag character
|
||||
break;
|
||||
}
|
||||
// check for and skip the optional field width
|
||||
while ( format[index] != '\0' && format[index] >= '0' && format[index] <= '9') {
|
||||
index++;
|
||||
}
|
||||
// Check for an skip the optional precision
|
||||
if ( format[index] != '\0' && format[index] == '.') {
|
||||
index++; // skip the period
|
||||
while ( format[index] != '\0' && format[index] >= '0' && format[index] <= '9') {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
// Check for and skip the optional length modifiers
|
||||
lmod = ' ';
|
||||
switch( format[index]) {
|
||||
case 'h' : if ( format[++index] == 'h') {
|
||||
++index; //also recognize the 'hh' modifier
|
||||
lmod = 'H'; // for char
|
||||
} else {
|
||||
lmod = 'h'; // for short
|
||||
}
|
||||
break;
|
||||
case 'l' : if ( format[++index] == 'l') {
|
||||
++index; //also recognize the 'll' modifier
|
||||
lmod = 'd'; // for long long
|
||||
} else {
|
||||
lmod = 'l'; // for long
|
||||
}
|
||||
break;
|
||||
case 'L' : lmod = 'L'; break;
|
||||
case 'j' :
|
||||
case 'z' :
|
||||
case 't' : index++;
|
||||
break;
|
||||
}
|
||||
|
||||
// Recognize and record the actual modifier
|
||||
switch( format[index]) {
|
||||
case 'c' :
|
||||
if ( lmod == 'l') {
|
||||
pformatList[numFormats] = FMT_WCHAR; // store the format character
|
||||
} else {
|
||||
pformatList[numFormats] = FMT_CHAR;
|
||||
}
|
||||
numFormats++;
|
||||
index++; // skip the format character
|
||||
break;
|
||||
|
||||
case 'd' : case 'i' : // signed
|
||||
case 'o' : case 'u' : // unsigned
|
||||
case 'x' : case 'X' : // unsigned
|
||||
if ( lmod == 'H') {
|
||||
pformatList[numFormats] = FMT_CHAR; // store the format character
|
||||
} else if ( lmod == 'l') {
|
||||
pformatList[numFormats] = FMT_LONG; // store the format character
|
||||
} else if ( lmod == 'h') {
|
||||
pformatList[numFormats] = FMT_SHORT; // store the format character
|
||||
} else{
|
||||
pformatList[numFormats] = FMT_INT;
|
||||
}
|
||||
numFormats++;
|
||||
index++; // skip the format character
|
||||
break;
|
||||
|
||||
case 'e' : case 'E' :
|
||||
case 'f' : case 'F' :
|
||||
case 'g' : case 'G' :
|
||||
case 'a' : case 'A' :
|
||||
if ( lmod == 'L') {
|
||||
pformatList[numFormats] = FMT_LDOUBLE; // store the format character
|
||||
} else{
|
||||
pformatList[numFormats] = FMT_DOUBLE;
|
||||
}
|
||||
numFormats++;
|
||||
index++; // skip the format character
|
||||
break;
|
||||
|
||||
case 's' :
|
||||
if ( lmod == 'l' || lmod == 'L') {
|
||||
pformatList[numFormats] = FMT_WSTRING; // store the format character
|
||||
} else {
|
||||
pformatList[numFormats] = FMT_STRING;
|
||||
}
|
||||
numFormats++;
|
||||
index++; // skip the format character
|
||||
break;
|
||||
|
||||
case 'p' :
|
||||
pformatList[numFormats] = FMT_VOID;
|
||||
numFormats++;
|
||||
index++; // skip the format character
|
||||
break;
|
||||
|
||||
case 'n' :
|
||||
if ( lmod == 'H') {
|
||||
pformatList[numFormats] = FMT_PCHAR; // store the format character
|
||||
} else if ( lmod == 'l') {
|
||||
pformatList[numFormats] = FMT_PLONG; // store the format character
|
||||
} else if ( lmod == 'h') {
|
||||
pformatList[numFormats] = FMT_PSHORT; // store the format character
|
||||
} else{
|
||||
pformatList[numFormats] = FMT_PINT;
|
||||
}
|
||||
numFormats++;
|
||||
index++; // skip the format character
|
||||
break;
|
||||
case 'm' :
|
||||
// Does not represent an argument in the call stack
|
||||
index++; // skip the format character
|
||||
continue;
|
||||
default:
|
||||
printf("failed to recognize format string [");
|
||||
for (;start<index; start++) { printf("%c", format[start]); }
|
||||
puts("]");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
index++; // move past this character
|
||||
}
|
||||
}
|
||||
|
||||
return numFormats;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
check_integer_format(const char format)
|
||||
{
|
||||
unsigned int retValue = 0; // default failure
|
||||
switch( format) {
|
||||
case FMT_CHAR :
|
||||
case FMT_SHORT :
|
||||
case FMT_INT :
|
||||
retValue = 1;
|
||||
break;
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int snprintf_s_i(char *dest, rsize_t dmax, const char *format, int a)
|
||||
{
|
||||
char pformatList[MAX_FORMAT_ELEMENTS];
|
||||
unsigned int index = 0;
|
||||
|
||||
// Determine the number of format options in the format string
|
||||
unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS);
|
||||
|
||||
// Check that there are not too many format options
|
||||
if ( nfo != 1 ) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESBADFMT);
|
||||
}
|
||||
// Check that the format is for an integer type
|
||||
if ( check_integer_format(pformatList[index]) == 0) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESFMTTYP);
|
||||
}
|
||||
index++;
|
||||
|
||||
return snprintf(dest, dmax, format, a);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int snprintf_s_l(char *dest, rsize_t dmax, const char *format, long a)
|
||||
{
|
||||
char pformatList[MAX_FORMAT_ELEMENTS];
|
||||
unsigned int index = 0;
|
||||
|
||||
// Determine the number of format options in the format string
|
||||
unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS);
|
||||
|
||||
// Check that there are not too many format options
|
||||
if ( nfo != 1 ) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESBADFMT);
|
||||
}
|
||||
// Check that the format is for an long type
|
||||
if ( CHK_FORMAT(FMT_LONG, pformatList[index]) == 0) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESFMTTYP);
|
||||
}
|
||||
index++;
|
||||
|
||||
return snprintf(dest, dmax, format, a);
|
||||
}
|
||||
|
||||
|
||||
inline int snprintf_s_si(char *dest, rsize_t dmax, const char *format, char *s, int a)
|
||||
{
|
||||
char pformatList[MAX_FORMAT_ELEMENTS];
|
||||
unsigned int index = 0;
|
||||
|
||||
// Determine the number of format options in the format string
|
||||
unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS);
|
||||
|
||||
// Check that there are not too many format options
|
||||
if ( nfo != 2 ) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESBADFMT);
|
||||
}
|
||||
// Check first format is of string type
|
||||
if ( CHK_FORMAT(FMT_STRING, pformatList[index]) == 0) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESFMTTYP);
|
||||
}
|
||||
index++;
|
||||
|
||||
// Check that the format is for an integer type
|
||||
if ( check_integer_format(pformatList[index]) == 0) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESFMTTYP);
|
||||
}
|
||||
index++;
|
||||
|
||||
return snprintf(dest, dmax, format, s, a);
|
||||
}
|
||||
|
||||
|
||||
inline int snprintf_s_sl(char *dest, rsize_t dmax, const char *format, char *s, long a)
|
||||
{
|
||||
char pformatList[MAX_FORMAT_ELEMENTS];
|
||||
unsigned int index = 0;
|
||||
|
||||
// Determine the number of format options in the format string
|
||||
unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS);
|
||||
|
||||
// Check that there are not too many format options
|
||||
if ( nfo != 2 ) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESBADFMT);
|
||||
}
|
||||
// Check first format is of string type
|
||||
if ( CHK_FORMAT(FMT_STRING, pformatList[index]) == 0) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESFMTTYP);
|
||||
}
|
||||
index++;
|
||||
|
||||
// Check that the format is for an integer type
|
||||
if ( CHK_FORMAT(FMT_LONG, pformatList[index]) == 0) {
|
||||
dest[0] = '\0';
|
||||
return SNPRFNEGATE(ESFMTTYP);
|
||||
}
|
||||
index++;
|
||||
|
||||
return snprintf(dest, dmax, format, s, a);
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
/*------------------------------------------------------------------
|
||||
* stpcpy_s.c
|
||||
*
|
||||
* August 2014, D Wheeler
|
||||
*
|
||||
* Copyright (c) 2014 by Intel Corp
|
||||
* 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
|
||||
* stpcpy_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* char *
|
||||
* stpcpy_s(char *dest, rsize_t dmax, const char *src, errno_t *err);
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The stpcpy_s function copies the string pointed to by src
|
||||
* (including the terminating null character) into the array
|
||||
* pointed to by dest. All elements following the terminating
|
||||
* null character (if any) written by stpcpy_s in the array
|
||||
* of dmax characters pointed to by dest are nulled when
|
||||
* strcpy_s returns. The function returns a pointer to the
|
||||
* end of the string in dest - that is to the null terminator
|
||||
* of dest - upon return. If an error occurs, NULL is returned
|
||||
* and err is set to the error encountered.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string that will be replaced by src.
|
||||
*
|
||||
* dmax restricted maximum length of dest
|
||||
*
|
||||
* src pointer to the string that will be copied
|
||||
* to dest
|
||||
*
|
||||
* err the error code upon error, or EOK if successful
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest updated
|
||||
* err updated as follows:
|
||||
* EOK successful operation, the characters in src were
|
||||
* copied into dest and the result is null terminated.
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESOVRLP strings overlap
|
||||
* ESNOSPC not enough space to copy src
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall be greater than strnlen_s(src, dmax).
|
||||
* Copying shall not take place between objects that overlap.
|
||||
* If there is a runtime-constraint violation, then if dest
|
||||
* is not a null pointer and destmax is greater than zero and
|
||||
* not greater than RSIZE_MAX_STR, then stpcpy_s nulls dest.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* a char pointer to the terminating null at the end of dest
|
||||
*
|
||||
* ALSO SEE
|
||||
* strcpy_s(), strcat_s(), strncat_s(), strncpy_s()
|
||||
*
|
||||
*/
|
||||
char *
|
||||
stpcpy_s(char *dest, rsize_t dmax, const char *src, errno_t *err)
|
||||
{
|
||||
rsize_t orig_dmax;
|
||||
char *orig_dest;
|
||||
const char *overlap_bumper;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("stpcpy_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
*err = RCNEGATE(ESNULLP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("stpcpy_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
*err = RCNEGATE(ESZEROL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("stpcpy_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
*err = RCNEGATE(ESLEMAX);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#else
|
||||
*dest = '\0';
|
||||
#endif
|
||||
invoke_safe_str_constraint_handler("stpcpy_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
*err = RCNEGATE(ESNULLP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* hold base of dest in case src was not copied */
|
||||
orig_dmax = dmax;
|
||||
orig_dest = dest;
|
||||
|
||||
if (dest == src) {
|
||||
/* look for the terminating null character, or return err if not found in dmax bytes */
|
||||
while (dmax > 0) {
|
||||
if (*dest == '\0') {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null slack to clear any data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#endif
|
||||
*err = RCNEGATE(EOK);
|
||||
return dest;
|
||||
}
|
||||
|
||||
dmax--;
|
||||
dest++;
|
||||
}
|
||||
/* null terminator not found in src before end of dmax */
|
||||
handle_error(orig_dest, orig_dmax, "stpcpy_s: not enough space for src",
|
||||
ESNOSPC);
|
||||
*err = RCNEGATE(ESNOSPC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (dest < src) {
|
||||
overlap_bumper = src;
|
||||
|
||||
/* Check that the dest buffer does not overlap src buffer */
|
||||
while (dmax > 0) {
|
||||
if (dest == overlap_bumper) {
|
||||
handle_error(orig_dest, orig_dmax, "stpcpy_s: "
|
||||
"overlapping objects",
|
||||
ESOVRLP);
|
||||
*err = RCNEGATE(ESOVRLP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*dest = *src;
|
||||
if (*dest == '\0') {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null slack to clear any data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#endif
|
||||
*err = RCNEGATE(EOK);
|
||||
return dest;
|
||||
}
|
||||
|
||||
dmax--;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
} else {
|
||||
overlap_bumper = dest;
|
||||
|
||||
while (dmax > 0) {
|
||||
/* check that the src buffer does not run into the dest buffer - inifinite loop */
|
||||
if (src == overlap_bumper) {
|
||||
/* NOTE (dmw) this condition guarantees that SRC has already been damaged! */
|
||||
handle_error(orig_dest, orig_dmax, "stpcpy_s: overlapping objects",
|
||||
ESOVRLP);
|
||||
*err = RCNEGATE(ESOVRLP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*dest = *src;
|
||||
if (*dest == '\0') {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null slack to clear any data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#endif
|
||||
*err = RCNEGATE(EOK);
|
||||
return dest;
|
||||
}
|
||||
|
||||
dmax--;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Ran out of space in dest, and did not find the null terminator in src
|
||||
*/
|
||||
handle_error(orig_dest, orig_dmax, "stpcpy_s: not "
|
||||
"enough space for src",
|
||||
ESNOSPC);
|
||||
*err = RCNEGATE(ESNOSPC);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(stpcpy_s)
|
|
@ -0,0 +1,282 @@
|
|||
/*------------------------------------------------------------------
|
||||
* stpncpy_s.c
|
||||
*
|
||||
* August 2014, D Wheeler
|
||||
*
|
||||
* Copyright (c) 2014 by Intel Corp
|
||||
* 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
|
||||
* stpncpy_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* char *
|
||||
* stpncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t smax, errno_t *err);
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The stpncpy_s function copies at most smax characters from the string
|
||||
* pointed to by src, including the terminating null byte ('\0'), to the
|
||||
* array pointed to by dest. Exactly smax characters are written at dest.
|
||||
* If the length strlen_s(src) is smaller than smax, the remaining smax
|
||||
* characters in the array pointed to by dest are filled with null bytes.
|
||||
* If the length strlen_s(src) is greater than or equal to smax, the string
|
||||
* pointed to by dest will contain smax characters from src plus a null
|
||||
* characters (dest will be null-terminated).
|
||||
*
|
||||
* Therefore, dmax must be at least smax+1 in order to contain the terminator.
|
||||
*
|
||||
* The function returns a pointer to the end of the string in dest -
|
||||
* that is to the null terminator of dest. If an error occurs,
|
||||
* NULL is returned and err is set to the error encountered.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string that will be replaced by src.
|
||||
*
|
||||
* dmax restricted maximum length of dest (must be at least smax+1)
|
||||
*
|
||||
* src pointer to the string that will be copied
|
||||
* to dest
|
||||
*
|
||||
* smax the maximum number of characters from src to copy into dest
|
||||
*
|
||||
* err the error code upon error, or EOK if successful
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest updated
|
||||
* err updated as follows:
|
||||
* EOK successful operation, the characters in src were
|
||||
* copied into dest and the result is null terminated,
|
||||
* and dest is returned to point to the first null at end of dest.
|
||||
* On error, NULL is returned and err is set to one of hte following:
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESOVRLP strings overlap
|
||||
* ESNOSPC not enough space to copy src
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
* dmax shall not equal zero.
|
||||
* dmax must be at least smax+1 to allow filling dest with smax characters plus NULL.
|
||||
* If src and dest overlap, copying shall be stopped; destruction of src may have occurred.
|
||||
* If there is a runtime-constraint violation, then:
|
||||
* if dest is not a null pointer and dmax is greater than zero and
|
||||
* not greater than RSIZE_MAX_STR, then stpncpy_s shall fill dest with nulls,
|
||||
* if library was compiled with SAFECLIB_STR_NULL_SLACK.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* a char pointer to the terminating null at the end of dest
|
||||
* or NULL pointer on error
|
||||
*
|
||||
* ALSO SEE
|
||||
* stpcpy_s(), strcpy_s(), strcat_s(), strncat_s(), strncpy_s()
|
||||
*
|
||||
*/
|
||||
char *
|
||||
stpncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t smax, errno_t *err)
|
||||
{
|
||||
rsize_t orig_dmax;
|
||||
char *orig_dest;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
*err = RCNEGATE(ESNULLP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
*err = RCNEGATE(ESNULLP);
|
||||
dest[0] = '\0';
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
*err = RCNEGATE(ESZEROL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
*err = RCNEGATE(ESLEMAX);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (smax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: smax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
*err = RCNEGATE(ESLEMAX);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dmax < (smax+1)) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: dmax too short for smax",
|
||||
NULL, ESNOSPC);
|
||||
*err = RCNEGATE(ESNOSPC);
|
||||
dest[0] = '\0';
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* dmwheel1: Add check to prevent destruction of overlap into destination */
|
||||
if ((src < dest) && ((src+smax) >= dest)) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: src+smax overlaps into dest",
|
||||
NULL, ESOVRLP);
|
||||
*err = RCNEGATE(ESOVRLP);
|
||||
dest[0] = '\0';
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* dmwheel1: Add check to prevent destruction of overlap into source */
|
||||
if ((dest < src) && ((dest+smax) >= src)) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: dest+smax overlaps into src",
|
||||
NULL, ESOVRLP);
|
||||
*err = RCNEGATE(ESOVRLP);
|
||||
dest[0] = '\0';
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* dmwheel1: Add check to prevent destruction of overlap into destination */
|
||||
if ((src < dest) && ((src+dmax) >= dest)) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: src+dmax overlaps into dest",
|
||||
NULL, ESOVRLP);
|
||||
*err = RCNEGATE(ESOVRLP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* dmwheel1: Add check to prevent destruction of overlap into source */
|
||||
if ((dest < src) && ((dest+dmax) >= src)) {
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: dest+dmax overlaps into src",
|
||||
NULL, ESOVRLP);
|
||||
*err = RCNEGATE(ESOVRLP);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (src == NULL) {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#else
|
||||
*dest = '\0';
|
||||
#endif
|
||||
invoke_safe_str_constraint_handler("stpncpy_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
*err = RCNEGATE(ESNULLP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* hold base of dest in case src was not copied */
|
||||
orig_dmax = dmax;
|
||||
orig_dest = dest;
|
||||
|
||||
if (dest == src) {
|
||||
/* look for the terminating null character, or return err if not found in dmax bytes */
|
||||
while (dmax > 0) {
|
||||
if (*dest == '\0') {
|
||||
/* add nulls to complete smax */
|
||||
char *filler = dest; /* don't change dest, because we need to return it */
|
||||
while (smax) { *filler = '\0'; dmax--; smax--; filler++; }
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null dmax slack to clear any data */
|
||||
while (dmax) { *filler = '\0'; dmax--; filler++; }
|
||||
#endif
|
||||
*err = RCNEGATE(EOK);
|
||||
return dest;
|
||||
}
|
||||
dmax--;
|
||||
dest++;
|
||||
if (--smax == 0) {
|
||||
/* we have copied smax characters, add null terminator */
|
||||
*dest = '\0';
|
||||
}
|
||||
}
|
||||
/* null terminator not found in src before end of dmax */
|
||||
handle_error(orig_dest, orig_dmax, "stpncpy_s: not enough space for src",
|
||||
ESNOSPC);
|
||||
*err = RCNEGATE(ESNOSPC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* All checks for buffer overlaps were made, just do the copies */
|
||||
while (dmax > 0) {
|
||||
|
||||
*dest = *src; /* Copy the data into the destination */
|
||||
|
||||
/* Check for maximum copy from source */
|
||||
if (smax == 0) {
|
||||
/* we have copied smax characters, add null terminator */
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
/* Check for end of copying */
|
||||
if (*dest == '\0') {
|
||||
/* add nulls to complete smax, if fewer than smax characters
|
||||
* were in src when the NULL was encountered */
|
||||
char *filler = dest; /* don't change dest, because we need to return it */
|
||||
while (smax) { *filler = '\0'; dmax--; smax--; filler++; }
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null dmax slack to clear any data */
|
||||
while (dmax) { *filler = '\0'; dmax--; filler++; }
|
||||
#endif
|
||||
*err = RCNEGATE(EOK);
|
||||
return dest;
|
||||
}
|
||||
dmax--;
|
||||
smax--;
|
||||
dest++;
|
||||
src++;
|
||||
|
||||
}
|
||||
/*
|
||||
* Ran out of space in dest, and did not find the null terminator in src
|
||||
*/
|
||||
handle_error(orig_dest, orig_dmax, "stpncpy_s: not enough space for src",
|
||||
ESNOSPC);
|
||||
*err = RCNEGATE(ESNOSPC);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(stpncpy_s)
|
|
@ -0,0 +1,144 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcasecmp_s.c
|
||||
*
|
||||
* November 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
|
||||
* strcasecmp_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcasecmp_s(const char *dest, rsize_t dmax,
|
||||
* const char *src, int *indicator)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Case insensitive string comparison by converting
|
||||
* to uppercase prior to the compare.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string to compare against
|
||||
*
|
||||
* dmax restricted maximum length of string dest
|
||||
*
|
||||
* src pointer to the string to be compared to dest
|
||||
*
|
||||
* indicator pointer to result indicator, greater than 0,
|
||||
* equal to 0 or less than 0, if the string pointed
|
||||
* to by dest is greater than, equal to or less
|
||||
* than the string pointed to by src respectively.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* indicator shall not be a null pointer.
|
||||
* dmax shall not be 0
|
||||
* dmax shall not be greater than RSIZE_MAX_STR
|
||||
*
|
||||
* RETURN VALUE
|
||||
* indicator, when the return code is OK
|
||||
* >0 dest greater than src
|
||||
* 0 strings the same
|
||||
* <0 dest less than src
|
||||
*
|
||||
* EOK comparison complete
|
||||
* ESNULLP pointer was null
|
||||
* ESZEROL length was zero
|
||||
* ESLEMAX length exceeded max
|
||||
*
|
||||
* ALSO SEE
|
||||
* strcmp_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcasecmp_s (const char *dest, rsize_t dmax,
|
||||
const char *src, int *indicator)
|
||||
{
|
||||
const unsigned char *udest = (const unsigned char *) dest;
|
||||
const unsigned char *usrc = (const unsigned char *) src;
|
||||
|
||||
if (indicator == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcasecmp_s: indicator is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
*indicator = 0;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcasecmp_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcasecmp_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strcasecmp_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcasecmp_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
while (*udest && *usrc && dmax) {
|
||||
|
||||
if (toupper(*udest) != toupper(*usrc)) {
|
||||
break;
|
||||
}
|
||||
|
||||
udest++;
|
||||
usrc++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
*indicator = (toupper(*udest) - toupper(*usrc));
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
EXPORT_SYMBOL(strcasecmp_s)
|
|
@ -0,0 +1,180 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcasestr_s.c
|
||||
*
|
||||
* November 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
|
||||
* strcasestr_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcasestr_s(char *dest, rsize_t dmax,
|
||||
* const char *src, rsize_t slen, char **substring)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The strcasestr_s() function locates the first occurrence of
|
||||
* the substring pointed to by src which would be located in
|
||||
* the string pointed to by dest. The comparison is case
|
||||
* insensitive.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string to be searched for the substring
|
||||
*
|
||||
* dmax restricted maximum length of dest string
|
||||
*
|
||||
* src pointer to the sub string
|
||||
*
|
||||
* slen maximum length of src string
|
||||
*
|
||||
* substring returned pointer to the substring
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* substring pointer to the substring
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor slen shall equal zero.
|
||||
* Neither dmax nor slen shall be greater than RSIZE_MAX_STR.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation, substring found.
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESNOTFND substring not found
|
||||
*
|
||||
* ALSO SEE
|
||||
* strstr_s(), strprefix_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcasestr_s (char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t slen, char **substring)
|
||||
{
|
||||
rsize_t len;
|
||||
rsize_t dlen;
|
||||
int i;
|
||||
|
||||
if (substring == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcasestr_s: substring is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
*substring = NULL;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcasestr_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strcasestr_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcasestr_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcasestr_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (slen == 0) {
|
||||
invoke_safe_str_constraint_handler("strcasestr_s: slen is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (slen > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcasestr_s: slen exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
/*
|
||||
* src points to a string with zero length, or
|
||||
* src equals dest, return dest
|
||||
*/
|
||||
if (*src == '\0' || dest == src) {
|
||||
*substring = dest;
|
||||
return (EOK);
|
||||
}
|
||||
|
||||
while (*dest && dmax) {
|
||||
i = 0;
|
||||
len = slen;
|
||||
dlen = dmax;
|
||||
|
||||
while (dest[i] && dlen) {
|
||||
|
||||
/* not a match, not a substring */
|
||||
if (toupper(dest[i]) != toupper(src[i])) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* move to the next char */
|
||||
i++;
|
||||
len--;
|
||||
dlen--;
|
||||
|
||||
if (src[i] == '\0' || !len) {
|
||||
*substring = dest;
|
||||
return (EOK);
|
||||
}
|
||||
}
|
||||
dest++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
/*
|
||||
* substring was not found, return NULL
|
||||
*/
|
||||
*substring = NULL;
|
||||
return (ESNOTFND);
|
||||
}
|
||||
EXPORT_SYMBOL(strcasestr_s)
|
|
@ -0,0 +1,232 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcat_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
|
||||
* strcat_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcat_s(char *dest, rsize_t dmax, const char *src)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The strcat_s function appends a copy of the string pointed
|
||||
* to by src (including the terminating null character) to the
|
||||
* end of the string pointed to by dest. The initial character
|
||||
* from src overwrites the null character at the end ofdest.
|
||||
*
|
||||
* All elements following the terminating null character (if
|
||||
* any) written by strcat_s in the array of dmax characters
|
||||
* pointed to by dest take unspecified values when strcat_s
|
||||
* returns.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string that will be extended by src
|
||||
* if dmax allows. The string is null terminated.
|
||||
* If the resulting concatenated string is less
|
||||
* than dmax, the remaining slack space is nulled.
|
||||
*
|
||||
* dmax restricted maximum length of the resulting dest,
|
||||
* including the null
|
||||
*
|
||||
* src pointer to the string that will be concatenaed
|
||||
* to string dest
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer
|
||||
* dmax shall not equal zero
|
||||
* dmax shall not be greater than RSIZE_MAX_STR
|
||||
* dmax shall be greater than strnlen_s(src,m).
|
||||
* Copying shall not takeplace between objects that overlap
|
||||
* If there is a runtime-constraint violation, then if dest is
|
||||
* not a null pointer and dmax is greater than zero and not
|
||||
* greater than RSIZE_MAX_STR, then strcat_s nulls dest.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation, all the characters from src
|
||||
* were appended to dest and the result in dest is
|
||||
* null terminated.
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max
|
||||
* ESUNTERM dest not terminated
|
||||
*
|
||||
* ALSO SEE
|
||||
* strncat_s(), strcpy_s(), strncpy_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcat_s (char *dest, rsize_t dmax, const char *src)
|
||||
{
|
||||
rsize_t orig_dmax;
|
||||
char *orig_dest;
|
||||
const char *overlap_bumper;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcat_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcat_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strcat_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcat_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
/* hold base of dest in case src was not copied */
|
||||
orig_dmax = dmax;
|
||||
orig_dest = dest;
|
||||
|
||||
if (dest < src) {
|
||||
overlap_bumper = src;
|
||||
|
||||
/* Find the end of dest */
|
||||
while (*dest != '\0') {
|
||||
|
||||
if (dest == overlap_bumper) {
|
||||
handle_error(orig_dest, orig_dmax, "strcat_s: "
|
||||
"overlapping objects",
|
||||
ESOVRLP);
|
||||
return RCNEGATE(ESOVRLP);
|
||||
}
|
||||
|
||||
dest++;
|
||||
dmax--;
|
||||
if (dmax == 0) {
|
||||
handle_error(orig_dest, orig_dmax, "strcat_s: "
|
||||
"dest unterminated",
|
||||
ESUNTERM);
|
||||
return RCNEGATE(ESUNTERM);
|
||||
}
|
||||
}
|
||||
|
||||
while (dmax > 0) {
|
||||
if (dest == overlap_bumper) {
|
||||
handle_error(orig_dest, orig_dmax, "strcat_s: "
|
||||
"overlapping objects",
|
||||
ESOVRLP);
|
||||
return RCNEGATE(ESOVRLP);
|
||||
}
|
||||
|
||||
*dest = *src;
|
||||
if (*dest == '\0') {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null slack to clear any data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#endif
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
|
||||
dmax--;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
} else {
|
||||
overlap_bumper = dest;
|
||||
|
||||
/* Find the end of dest */
|
||||
while (*dest != '\0') {
|
||||
|
||||
/*
|
||||
* NOTE: no need to check for overlap here since src comes first
|
||||
* in memory and we're not incrementing src here.
|
||||
*/
|
||||
dest++;
|
||||
dmax--;
|
||||
if (dmax == 0) {
|
||||
handle_error(orig_dest, orig_dmax, "strcat_s: "
|
||||
"dest unterminated",
|
||||
ESUNTERM);
|
||||
return RCNEGATE(ESUNTERM);
|
||||
}
|
||||
}
|
||||
|
||||
while (dmax > 0) {
|
||||
if (src == overlap_bumper) {
|
||||
handle_error(orig_dest, orig_dmax, "strcat_s: "
|
||||
"overlapping objects",
|
||||
ESOVRLP);
|
||||
return RCNEGATE(ESOVRLP);
|
||||
}
|
||||
|
||||
*dest = *src;
|
||||
if (*dest == '\0') {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null slack to clear any data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#endif
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
|
||||
dmax--;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* the entire src was not copied, so null the string
|
||||
*/
|
||||
handle_error(orig_dest, orig_dmax, "strcat_s: not enough "
|
||||
"space for src",
|
||||
ESNOSPC);
|
||||
|
||||
return RCNEGATE(ESNOSPC);
|
||||
}
|
||||
EXPORT_SYMBOL(strcat_s)
|
|
@ -0,0 +1,140 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcmp_s.c -- string compare
|
||||
*
|
||||
* November 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
|
||||
* strcmp_s
|
||||
*
|
||||
* Synpsos
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcmp_s(const char *dest, rsize_t dmax,
|
||||
* const char *src, int *indicator)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Compares string src to string dest.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string to compare against
|
||||
*
|
||||
* dmax restricted maximum length of string dest
|
||||
*
|
||||
* src pointer to the string to be compared to dest
|
||||
*
|
||||
* indicator pointer to result indicator, greater than,
|
||||
* equal to or less than 0, if the string pointed
|
||||
* to by dest is greater than, equal to or less
|
||||
* than the string pointed to by src respectively.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* indicator updated result indicator
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* indicator shall not be a null pointer.
|
||||
* dmax shall not be 0
|
||||
* dmax shall not be greater than RSIZE_MAX_STR
|
||||
*
|
||||
* RETURN VALUE
|
||||
* indicator, when the return code is OK
|
||||
* >0 dest greater than src
|
||||
* 0 strings the same
|
||||
* <0 dest less than src
|
||||
*
|
||||
* EOK
|
||||
* ESNULLP pointer was null
|
||||
* ESZEROL length was zero
|
||||
* ESLEMAX length exceeded max
|
||||
*
|
||||
* ALSO SEE
|
||||
* strcasecmp_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcmp_s (const char *dest, rsize_t dmax,
|
||||
const char *src, int *indicator)
|
||||
{
|
||||
if (indicator == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcmp_s: indicator is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
*indicator = 0;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcmp_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcmp_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strcmp_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcmp_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
while (*dest && *src && dmax) {
|
||||
|
||||
if (*dest != *src) {
|
||||
break;
|
||||
}
|
||||
|
||||
dest++;
|
||||
src++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
*indicator = *dest - *src;
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
EXPORT_SYMBOL(strcmp_s)
|
|
@ -0,0 +1,143 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcmpfld_s.c
|
||||
*
|
||||
* November 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
|
||||
* strcmpfld_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcmpfld_s(const char *dest, rsize_t dmax,
|
||||
* const char *src, int *indicator)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Compares the character array pointed to by src to the character array
|
||||
* pointed to by dest for dmax characters. The null terminator does not
|
||||
* stop the comparison.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to character array to compare against
|
||||
*
|
||||
* dmax restricted maximum length of dest. The length is
|
||||
* used for the comparison of src against dest.
|
||||
*
|
||||
* src pointer to the character array to be compared to dest
|
||||
*
|
||||
* indicator pointer to result indicator, greater than, equal
|
||||
* to or less than 0, if the character array pointed
|
||||
* to by dest is greater than, equal to or less
|
||||
* than the character array pointed to by src.
|
||||
* OUTPUT
|
||||
* indicator updated result indicator
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* indicator shall not be a null pointer.
|
||||
* dmax shall not be 0
|
||||
* dmax shall not be greater than RSIZE_MAX_STR
|
||||
*
|
||||
* RETURN VALUE
|
||||
* indicator, when the return code is OK
|
||||
* >0 dest greater than src
|
||||
* 0 strings the same
|
||||
* <0 dest less than src
|
||||
*
|
||||
* EOK
|
||||
* ESNULLP pointer was null
|
||||
* ESZEROL length was zero
|
||||
* ESLEMAX length exceeded max
|
||||
*
|
||||
* ALSO SEE
|
||||
* strcpyfld_s(), strcpyfldin_s(), strcpyfldout_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcmpfld_s (const char *dest, rsize_t dmax,
|
||||
const char *src, int *indicator)
|
||||
{
|
||||
if (indicator == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcmpfld_s: indicator is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
*indicator = 0;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcmpfld_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcmpfld_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strcmpfld_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcmpfld_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
/* compare for dmax charactrers, not the null! */
|
||||
while (dmax) {
|
||||
|
||||
if (*dest != *src) {
|
||||
break;
|
||||
}
|
||||
|
||||
dest++;
|
||||
src++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
*indicator = *dest - *src;
|
||||
return (EOK);
|
||||
}
|
||||
EXPORT_SYMBOL(strcmpfld_s)
|
|
@ -0,0 +1,198 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcpy_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
|
||||
* strcpy_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcpy_s(char *dest, rsize_t dmax, const char *src)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The strcpy_s function copies the string pointed to by src
|
||||
* (including the terminating null character) into the array
|
||||
* pointed to by dest. All elements following the terminating
|
||||
* null character (if any) written by strcpy_s in the array
|
||||
* of dmax characters pointed to by dest are nulled when
|
||||
* strcpy_s returns.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string that will be replaced by src.
|
||||
*
|
||||
* dmax restricted maximum length of dest
|
||||
*
|
||||
* src pointer to the string that will be copied
|
||||
* to dest
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall be greater than strnlen_s(src, dmax).
|
||||
* Copying shall not take place between objects that overlap.
|
||||
* If there is a runtime-constraint violation, then if dest
|
||||
* is not a null pointer and destmax is greater than zero and
|
||||
* not greater than RSIZE_MAX_STR, then strcpy_s nulls dest.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation, the characters in src were
|
||||
* copied into dest and the result is null terminated.
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESOVRLP strings overlap
|
||||
* ESNOSPC not enough space to copy src
|
||||
*
|
||||
* ALSO SEE
|
||||
* strcat_s(), strncat_s(), strncpy_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcpy_s (char *dest, rsize_t dmax, const char *src)
|
||||
{
|
||||
rsize_t orig_dmax;
|
||||
char *orig_dest;
|
||||
const char *overlap_bumper;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcpy_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strcpy_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcpy_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#else
|
||||
*dest = '\0';
|
||||
#endif
|
||||
invoke_safe_str_constraint_handler("strcpy_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (dest == src) {
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
|
||||
/* hold base of dest in case src was not copied */
|
||||
orig_dmax = dmax;
|
||||
orig_dest = dest;
|
||||
|
||||
if (dest < src) {
|
||||
overlap_bumper = src;
|
||||
|
||||
while (dmax > 0) {
|
||||
if (dest == overlap_bumper) {
|
||||
handle_error(orig_dest, orig_dmax, "strcpy_s: "
|
||||
"overlapping objects",
|
||||
ESOVRLP);
|
||||
return RCNEGATE(ESOVRLP);
|
||||
}
|
||||
|
||||
*dest = *src;
|
||||
if (*dest == '\0') {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null slack to clear any data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#endif
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
|
||||
dmax--;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
} else {
|
||||
overlap_bumper = dest;
|
||||
|
||||
while (dmax > 0) {
|
||||
if (src == overlap_bumper) {
|
||||
handle_error(orig_dest, orig_dmax, "strcpy_s: "
|
||||
"overlapping objects",
|
||||
ESOVRLP);
|
||||
return RCNEGATE(ESOVRLP);
|
||||
}
|
||||
|
||||
*dest = *src;
|
||||
if (*dest == '\0') {
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null slack to clear any data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
#endif
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
|
||||
dmax--;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* the entire src must have been copied, if not reset dest
|
||||
* to null the string.
|
||||
*/
|
||||
handle_error(orig_dest, orig_dmax, "strcpy_s: not "
|
||||
"enough space for src",
|
||||
ESNOSPC);
|
||||
return RCNEGATE(ESNOSPC);
|
||||
}
|
||||
EXPORT_SYMBOL(strcpy_s)
|
|
@ -0,0 +1,200 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcpyfld_s.c
|
||||
*
|
||||
* November 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
|
||||
* strcpyfld_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcpyfld_s(char *dest, rsize_t dmax, const char *src, rsize_t slen)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The strcpyfld_s function copies slen characters from the character
|
||||
* array pointed to by src into the character array pointed to by dest.
|
||||
* The copy operation does not stop on the null character as the
|
||||
* function copies slen characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* 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 character array that will be replaced by src.
|
||||
*
|
||||
* dmax restricted maximum length of dest
|
||||
*
|
||||
* src pointer to the character array that will be copied
|
||||
* to dest
|
||||
*
|
||||
* slen maximum length of src
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
* slen shall not equal zero.
|
||||
* slen shall not exceed dmax
|
||||
* Copying shall not take place between objects that overlap.
|
||||
* If there is a runtime-constraint violation, then if dest
|
||||
* is not a null pointer and destmax is greater than zero and
|
||||
* not greater than RSIZE_MAX_STR, then strcpyfld_s nulls dest.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESOVRLP strings overlap
|
||||
*
|
||||
* ALSO SEE
|
||||
* strcpyfldin_s(), strcpyfldout_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcpyfld_s (char *dest, rsize_t dmax, const char *src, rsize_t slen)
|
||||
{
|
||||
rsize_t orig_dmax;
|
||||
char *orig_dest;
|
||||
const char *overlap_bumper;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcpyfld_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strcpyfld_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcpyfld_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler("strcpyfld_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (slen == 0) {
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler("strcpyfld_s: slen is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (slen > dmax) {
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler("strcpyfld_s: src exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
|
||||
/* hold base of dest in case src was not copied */
|
||||
orig_dmax = dmax;
|
||||
orig_dest = dest;
|
||||
|
||||
if (dest < src) {
|
||||
overlap_bumper = src;
|
||||
|
||||
while (slen > 0) {
|
||||
|
||||
if (dest == overlap_bumper) {
|
||||
dmax = orig_dmax;
|
||||
dest = orig_dest;
|
||||
|
||||
/* null string to eliminate partial copy */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strcpyfld_s: overlapping objects",
|
||||
NULL, ESOVRLP);
|
||||
return (ESOVRLP);
|
||||
}
|
||||
|
||||
*dest++ = *src++;
|
||||
slen--;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
} else {
|
||||
overlap_bumper = dest;
|
||||
|
||||
while (slen > 0) {
|
||||
|
||||
if (src == overlap_bumper) {
|
||||
dmax = orig_dmax;
|
||||
dest = orig_dest;
|
||||
|
||||
/* null string to eliminate partial copy */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strcpyfld_s: overlapping objects",
|
||||
NULL, ESOVRLP);
|
||||
return (ESOVRLP);
|
||||
}
|
||||
|
||||
*dest++ = *src++;
|
||||
slen--;
|
||||
dmax--;
|
||||
}
|
||||
}
|
||||
|
||||
/* null slack space in the field */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
return (EOK);
|
||||
}
|
||||
EXPORT_SYMBOL(strcpyfld_s)
|
|
@ -0,0 +1,203 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcpyfldin_s.c
|
||||
*
|
||||
* November 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
|
||||
* strcpyfldin_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcpyfldin_s(char *dest, rsize_t dmax,
|
||||
* const char *src, rsize_t slen)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The strcpyfldin_s function copies at most slen characters from the
|
||||
* null terminated string pointed to by src into the fixed character
|
||||
* array pointed to by dest. The copy operation stops on the null
|
||||
* character if encountered and then continues to fill the field
|
||||
* with nulls up to dmax characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* 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 character array that will be replaced by src.
|
||||
*
|
||||
* dmax restricted maximum length of dest
|
||||
*
|
||||
* src pointer to the null terminated string that will be copied
|
||||
* into the character array pointed to by dest
|
||||
*
|
||||
* slen length of source
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
* slen shall not equal zero.
|
||||
* slen shall not exceed dmax
|
||||
* Copying shall not take place between objects that overlap.
|
||||
* If there is a runtime-constraint violation, then if dest
|
||||
* is not a null pointer and dmax is greater than zero and
|
||||
* not greater than RSIZE_MAX_STR, then strcpyfldin_s nulls dest.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESOVRLP strings overlap
|
||||
*
|
||||
* ALSO SEE
|
||||
* strcpyfld_s(), strcpyfldout_s(),
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcpyfldin_s (char *dest, rsize_t dmax, const char *src, rsize_t slen)
|
||||
{
|
||||
rsize_t orig_dmax;
|
||||
char *orig_dest;
|
||||
const char *overlap_bumper;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcpyfldin_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strcpyfldin_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcpyfldin_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler("strcpyfldin_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (slen == 0) {
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler("strcpyfldin_s: slen is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (slen > dmax) {
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler("strcpyfldin_s: slen exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
|
||||
/* hold base of dest in case src was not copied */
|
||||
orig_dmax = dmax;
|
||||
orig_dest = dest;
|
||||
|
||||
if (dest < src) {
|
||||
overlap_bumper = src;
|
||||
|
||||
while (dmax > 0 && *src) {
|
||||
|
||||
if (dest == overlap_bumper) {
|
||||
dmax = orig_dmax;
|
||||
dest = orig_dest;
|
||||
|
||||
/* null string to eliminate partial copy */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strcpyfldin_s: overlapping objects",
|
||||
NULL, ESOVRLP);
|
||||
return (ESOVRLP);
|
||||
}
|
||||
|
||||
dmax--;
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
} else {
|
||||
overlap_bumper = dest;
|
||||
|
||||
while (dmax > 0 && *src) {
|
||||
|
||||
if (src == overlap_bumper) {
|
||||
dmax = orig_dmax;
|
||||
dest = orig_dest;
|
||||
|
||||
/* null string to eliminate partial copy */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strcpyfldin_s: overlapping objects",
|
||||
NULL, ESOVRLP);
|
||||
return (ESOVRLP);
|
||||
}
|
||||
|
||||
dmax--;
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* finish filling in the field with nulls if there is slack space
|
||||
*/
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
return (EOK);
|
||||
}
|
||||
EXPORT_SYMBOL(strcpyfldin_s)
|
|
@ -0,0 +1,205 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcpyfldout_s.c
|
||||
*
|
||||
* November 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
|
||||
* strcpyfldout_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcpyfldout_s(char *dest, rsize_t dmax,
|
||||
* const char *src, rsize_t slen)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The strcpyfldout_s function copies slen characters from
|
||||
* the character array pointed to by src into the string
|
||||
* pointed to by dest. A null is included to properly
|
||||
* termiante the dest string. The copy operation does not
|
||||
* stop on the null character as function copies dmax
|
||||
* characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string that will be replaced by src.
|
||||
*
|
||||
* dmax restricted maximum length of dest
|
||||
*
|
||||
* src pointer to the character array to be copied
|
||||
* to dest and null terminated.
|
||||
*
|
||||
* slen the maximum number of characters that will be
|
||||
* copied from the src field into the dest string.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
* slen shall not equal zero.
|
||||
* slen shall not exceed dmax
|
||||
* Copying shall not take place between objects that overlap.
|
||||
* If there is a runtime-constraint violation, then if dest
|
||||
* is not a null pointer and dmax is greater than zero and
|
||||
* not greater than RSIZE_MAX_STR, then strcpyfldout_s nulls dest.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESOVRLP strings overlap
|
||||
*
|
||||
* ALSO SEE
|
||||
* strcpyfld_s(), strcpyfldin_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcpyfldout_s (char *dest, rsize_t dmax, const char *src, rsize_t slen)
|
||||
{
|
||||
rsize_t orig_dmax;
|
||||
char *orig_dest;
|
||||
const char *overlap_bumper;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcpyfldout_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strcpyfldout_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcpyfldout_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler("strcpyfldout_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (slen == 0) {
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler("strcpyfldout_s: slen is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (slen > dmax) {
|
||||
/* null string to clear data */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler("strcpyfldout_s: slen exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
|
||||
/* hold base of dest in case src was not copied */
|
||||
orig_dmax = dmax;
|
||||
orig_dest = dest;
|
||||
|
||||
if (dest < src) {
|
||||
overlap_bumper = src;
|
||||
|
||||
while (dmax > 1 && slen) {
|
||||
|
||||
if (dest == overlap_bumper) {
|
||||
dmax = orig_dmax;
|
||||
dest = orig_dest;
|
||||
|
||||
/* null string to eliminate partial copy */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strcpyfldout_s: overlapping objects",
|
||||
NULL, ESOVRLP);
|
||||
return (ESOVRLP);
|
||||
}
|
||||
|
||||
dmax--;
|
||||
slen--;
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
} else {
|
||||
overlap_bumper = dest;
|
||||
|
||||
while (dmax > 1 && slen) {
|
||||
|
||||
if (src == overlap_bumper) {
|
||||
dmax = orig_dmax;
|
||||
dest = orig_dest;
|
||||
|
||||
/* null string to eliminate partial copy */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strcpyfldout_s: overlapping objects",
|
||||
NULL, ESOVRLP);
|
||||
return (ESOVRLP);
|
||||
}
|
||||
|
||||
dmax--;
|
||||
slen--;
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
/* null slack space */
|
||||
while (dmax) { *dest = '\0'; dmax--; dest++; }
|
||||
|
||||
return (EOK);
|
||||
}
|
||||
EXPORT_SYMBOL(strcpyfldout_s)
|
|
@ -0,0 +1,165 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strcspn_s.c
|
||||
*
|
||||
* November 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
|
||||
* strcspn_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strcspn_s(const char *dest, rsize_t dmax,
|
||||
* const char *src, rsize_t slen, rsize_t *count)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function computes the prefix length of the string pointed
|
||||
* to by dest which consists entirely of characters that are
|
||||
* excluded from the string pointed to by src. The scanning stops
|
||||
* at the first null in dest or after dmax characters. The
|
||||
* exclusion string is checked to the null or after slen
|
||||
* characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string to determine the prefix
|
||||
*
|
||||
* dmax restricted maximum length of string dest
|
||||
*
|
||||
* src pointer to exclusion string
|
||||
*
|
||||
* slen restricted maximum length of string src
|
||||
*
|
||||
* count pointer to a count variable that will be updated
|
||||
* with the dest substring length
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* count updated count variable
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* count shall not be a null pointer.
|
||||
* dmax shall not be 0
|
||||
* dmax shall not be greater than RSIZE_MAX_STR
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK count
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* strspn_s(), strpbrk_s(), strstr_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strcspn_s (const char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t slen, rsize_t *count)
|
||||
{
|
||||
const char *scan2;
|
||||
rsize_t smax;
|
||||
|
||||
if (count== NULL) {
|
||||
invoke_safe_str_constraint_handler("strcspn_s: count is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
*count = 0;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcspn_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("strcspn_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0 ) {
|
||||
invoke_safe_str_constraint_handler("strcspn_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcspn_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
if (slen == 0 ) {
|
||||
invoke_safe_str_constraint_handler("strcspn_s: slen is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (slen > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strcspn_s: slen exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
while (*dest && dmax) {
|
||||
|
||||
/*
|
||||
* Scanning for exclusions, so if there is a match,
|
||||
* we're done!
|
||||
*/
|
||||
smax = slen;
|
||||
scan2 = src;
|
||||
while (*scan2 && smax) {
|
||||
|
||||
if (*dest == *scan2) {
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
scan2++;
|
||||
smax--;
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
dest++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
EXPORT_SYMBOL(strcspn_s)
|
|
@ -0,0 +1,128 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strfirstchar_s.c
|
||||
*
|
||||
* November 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
|
||||
* strfirstchar_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strfirstchar_s(char *dest, rsize_t dmax, char c, char **first)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function returns a pointer to the first occurrence
|
||||
* of character c in dest. The scanning stops at the first null
|
||||
* or after dmax characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string to compare against
|
||||
*
|
||||
* dmax restricted maximum length of string
|
||||
*
|
||||
* c character to locate
|
||||
*
|
||||
* first returned pointer to first occurrence of c
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* first updated pointer to first occurrence of c
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* first shall not be a null pointer.
|
||||
* dmax shall not be 0
|
||||
* dmax shall not be greater than RSIZE_MAX_STR
|
||||
*
|
||||
* RETURN VALUE
|
||||
* pointer to first occurence of c, NULL if not found
|
||||
*
|
||||
* EOK pointer to first occurrence is returned
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* strlastchar_s(), strfirstdiff_s(), strfirstsame_s(),
|
||||
* strlastdiff_s(), strlastsame_s(),
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strfirstchar_s (char *dest, rsize_t dmax, char c, char **first)
|
||||
{
|
||||
|
||||
if (first == NULL) {
|
||||
invoke_safe_str_constraint_handler("strfirstchar_s: index is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
*first = NULL;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strfirstchar_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0 ) {
|
||||
invoke_safe_str_constraint_handler("strfirstchar_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strfirstchar_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
while (*dest && dmax) {
|
||||
|
||||
if (*dest == c) {
|
||||
*first = dest;
|
||||
return (EOK);
|
||||
}
|
||||
dest++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
return (ESNOTFND);
|
||||
}
|
||||
EXPORT_SYMBOL(strfirstchar_s)
|
|
@ -0,0 +1,143 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strfirstdiff_s.c
|
||||
*
|
||||
* November 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
|
||||
* strfirstdiff_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strfirstdiff_s(const char *dest, rsize_t dmax,
|
||||
* const char *src, rsize_t *index)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Returns the index of the first character that is different
|
||||
* between dest and src. Index is valid only for OK.
|
||||
* The scanning stops at the first null in dest or src, or
|
||||
* after dmax characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string to compare against
|
||||
*
|
||||
* dmax restricted maximum length of string dest
|
||||
*
|
||||
* src pointer to the string to be compared to dest
|
||||
*
|
||||
* index pointer to returned index to first difference
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* index returned index to first difference
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* indicator shall not be a null pointer.
|
||||
* dmax shall not be 0.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* index to first difference, when the return code is OK
|
||||
*
|
||||
* EOK index to first diff is returned
|
||||
* ESNODIFF no difference
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
*
|
||||
* ALSO SEE
|
||||
* strfirstchar_s(), strfirstsame_s(), strlastchar_s(),
|
||||
* strlastdiff_s(), strlastsame_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strfirstdiff_s (const char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t *index)
|
||||
{
|
||||
const char *rp;
|
||||
|
||||
if (index == NULL) {
|
||||
invoke_safe_str_constraint_handler("strfirstdiff_s: index is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
*index = 0;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strfirstdiff_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("strfirstdiff_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0 ) {
|
||||
invoke_safe_str_constraint_handler("strfirstdiff_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strfirstdiff_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
/* hold reference point */
|
||||
rp = dest;
|
||||
|
||||
while (*dest && *src && dmax) {
|
||||
|
||||
if (*dest != *src) {
|
||||
*index = dest - rp;
|
||||
return (EOK);
|
||||
}
|
||||
dmax--;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
|
||||
return (ESNODIFF);
|
||||
}
|
||||
EXPORT_SYMBOL(strfirstdiff_s)
|
|
@ -0,0 +1,146 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strfirstsame_s.c
|
||||
*
|
||||
* November 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
|
||||
* strfirstsame_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* errno_t
|
||||
* strfirstsame_s(const char *dest, rsize_t dmax,
|
||||
* const char *src, rsize_t *index)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Returns the index of the first character that is the
|
||||
* same between dest and src. The scanning stops at the
|
||||
* fisrt null in dest or src, or after dmax characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string to compare against
|
||||
*
|
||||
* dmax restricted maximum length of string dest
|
||||
*
|
||||
* src pointer to the string to be compared to dest
|
||||
*
|
||||
* index pointer to returned index
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* index updated index
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* indicator shall not be a null pointer.
|
||||
* dmax shall not be 0
|
||||
* dmax shall not be greater than RSIZE_MAX_STR
|
||||
*
|
||||
* RETURN VALUE
|
||||
* index to first same char, when the return code is OK
|
||||
*
|
||||
* EOK index to first same char is returned
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESNOTFND not found
|
||||
*
|
||||
* ALSO SEE
|
||||
* strfirstchar_s(), strfirstdiff_s(), strlastchar_s(),
|
||||
* strlastdiff_s(), strlastsame_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
strfirstsame_s (const char *dest, rsize_t dmax,
|
||||
const char *src, rsize_t *index)
|
||||
{
|
||||
const char *rp = 0;
|
||||
|
||||
if (index == NULL) {
|
||||
invoke_safe_str_constraint_handler("strfirstsame_s: index is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
*index = 0;
|
||||
|
||||
if (dest == NULL) {
|
||||
invoke_safe_str_constraint_handler("strfirstsame_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
invoke_safe_str_constraint_handler("strfirstsame_s: src is null",
|
||||
NULL, ESNULLP);
|
||||
return (ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0 ) {
|
||||
invoke_safe_str_constraint_handler("strfirstsame_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strfirstsame_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (ESLEMAX);
|
||||
}
|
||||
|
||||
/* hold reference point */
|
||||
rp = dest;
|
||||
|
||||
/*
|
||||
* find the offset
|
||||
*/
|
||||
while (*dest && *src && dmax) {
|
||||
|
||||
if (*dest == *src) {
|
||||
*index = (uint32_t)(dest - rp);
|
||||
return (EOK);
|
||||
}
|
||||
|
||||
dest++;
|
||||
src++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
return (ESNOTFND);
|
||||
}
|
||||
EXPORT_SYMBOL(strfirstsame_s)
|
|
@ -0,0 +1,120 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strisalphanumeric_s.c
|
||||
*
|
||||
* November 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011, 2013 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
|
||||
* strisalphanumeric_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_dest_lib.h"
|
||||
* bool
|
||||
* strisalphanumeric_s(const char *dest, rsize_t dmax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function checks if the entire string contains
|
||||
* alphanumerics. The scanning stops at the first null
|
||||
* or after dmax characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string
|
||||
*
|
||||
* dmax maximum length of string
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* Runtime-condestaints
|
||||
* dest shall not be a null pointer.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* true dest is alphanumeric
|
||||
* false dest is not alphanumeric or an error occurred
|
||||
*
|
||||
* ALSO SEE
|
||||
* strisascii_s(), strisdigit_s(), strishex_s(), strislowercase_s(),
|
||||
* strismixedcase_s(), strisuppercase_s()
|
||||
*
|
||||
*/
|
||||
bool
|
||||
strisalphanumeric_s (const char *dest, rsize_t dmax)
|
||||
{
|
||||
if (!dest) {
|
||||
invoke_safe_str_constraint_handler("strisalphanumeric_s: "
|
||||
"dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strisalphanumeric_s: "
|
||||
"dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strisalphanumeric_s: "
|
||||
"dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (*dest == '\0') {
|
||||
return (false);
|
||||
}
|
||||
|
||||
while (*dest && dmax) {
|
||||
|
||||
if (( (*dest >= '0') && (*dest <= '9') ) ||
|
||||
( (*dest >= 'a') && (*dest <= 'z') ) ||
|
||||
( (*dest >= 'A') && (*dest <= 'Z') )) {
|
||||
dest++;
|
||||
dmax--;
|
||||
} else {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
EXPORT_SYMBOL(strisalphanumeric_s)
|
|
@ -0,0 +1,111 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strisascii_s.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011, 2013 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
|
||||
* strisascii_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* bool
|
||||
* strisascii_s(const char *dest, rsize_t dmax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function checks if the entire string contains ascii
|
||||
* characters. The scanning stops at the first null or
|
||||
* at most dmax characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string
|
||||
*
|
||||
* dmax maximum length of string
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* true, string is ascii
|
||||
* false, string contains one or more non-ascii or an error occurred
|
||||
*
|
||||
* ALSO SEE
|
||||
* strisalphanumeric_s(), strisdigit_s(), strishex_s(),
|
||||
* strislowercase_s(), strismixedcase_s(), strisuppercase_s()
|
||||
*-
|
||||
*/
|
||||
bool
|
||||
strisascii_s (const char *dest, rsize_t dmax)
|
||||
{
|
||||
if (!dest) {
|
||||
invoke_safe_str_constraint_handler("strisascii_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strisascii_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strisascii_s: dmax "
|
||||
"exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (false);
|
||||
}
|
||||
|
||||
while (*dest && dmax) {
|
||||
if ((unsigned char)*dest > 127) {
|
||||
return (false);
|
||||
}
|
||||
dest++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
EXPORT_SYMBOL(strisascii_s)
|
|
@ -0,0 +1,113 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strisdigit_s
|
||||
*
|
||||
* November 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011, 2013 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
|
||||
* strisdigit_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* bool
|
||||
* strisdigit_s(const char *dest, rsize_t dmax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function checks that the entire string contains digits.
|
||||
* The scanning stops at the first null or after dmax characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string
|
||||
*
|
||||
* dmax maximum length of string
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* true string is digit
|
||||
* false string is not digit or an error occurred
|
||||
*
|
||||
* ALSO SEE
|
||||
* strisalphanumeric_s(), strisascii_s(), strishex_s(),
|
||||
* strislowercase_s(), strismixedcase_s(), strisuppercase_s()
|
||||
*
|
||||
*/
|
||||
bool
|
||||
strisdigit_s (const char *dest, rsize_t dmax)
|
||||
{
|
||||
if (!dest) {
|
||||
invoke_safe_str_constraint_handler("strisdigit_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strisdigit_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strisdigit_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (*dest == '\0') {
|
||||
return (false);
|
||||
}
|
||||
|
||||
while (*dest) {
|
||||
|
||||
if ((*dest < '0') || (*dest > '9')) {
|
||||
return (false);
|
||||
}
|
||||
dest++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
EXPORT_SYMBOL(strisdigit_s)
|
|
@ -0,0 +1,119 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strishex_s.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011, 2013 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
|
||||
* strishex_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* bool
|
||||
* strishex_s(const char *dest, rsize_t dmax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function checks that the entire string contains
|
||||
* hex characters. The scanning stops at the first null
|
||||
* or after dmax characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string
|
||||
*
|
||||
* dmax maximum length of string
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* true string is hex
|
||||
* false string is not hex or an error occurred
|
||||
*
|
||||
* ALSO SEE
|
||||
* strisalphanumeric_s(), strisascii_s(), strisdigit_s(),
|
||||
* strislowercase_s(), strismixedcase_s(),
|
||||
* strisuppercase_s()
|
||||
*
|
||||
*/
|
||||
bool
|
||||
strishex_s (const char *dest, rsize_t dmax)
|
||||
{
|
||||
if (!dest) {
|
||||
invoke_safe_str_constraint_handler("strishex_s: dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strishex_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strishex_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (*dest == '\0') {
|
||||
return (false);
|
||||
}
|
||||
|
||||
while (*dest && dmax) {
|
||||
|
||||
if (((*dest >= '0') && (*dest <= '9')) ||
|
||||
((*dest >= 'a') && (*dest <= 'f')) ||
|
||||
((*dest >= 'A') && (*dest <= 'F'))) {
|
||||
dest++;
|
||||
dmax--;
|
||||
|
||||
} else {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
EXPORT_SYMBOL(strishex_s)
|
|
@ -0,0 +1,119 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strislowercase_s.c
|
||||
*
|
||||
* February 2005, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011, 2013 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
|
||||
* strislowercase_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* bool
|
||||
* strislowercase_s(const char *dest, rsize_t dmax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function checks if entire string is lowercase.
|
||||
* The scanning stops at the first null or after dmax
|
||||
* characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string
|
||||
*
|
||||
* dmax maximum length of string
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* dest shal be null terminated.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* true string is lowercase
|
||||
* false string is not lowercase or an error occurred
|
||||
*
|
||||
* ALSO SEE
|
||||
* strisalphanumeric_s(), strisascii_s(), strisdigit_s(),
|
||||
* strishex_s(), strismixedcase_s(),
|
||||
* strisuppercase_s()
|
||||
*
|
||||
*/
|
||||
bool
|
||||
strislowercase_s (const char *dest, rsize_t dmax)
|
||||
{
|
||||
if (!dest) {
|
||||
invoke_safe_str_constraint_handler("strislowercase_s: "
|
||||
"dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strislowercase_s: "
|
||||
"dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strislowercase_s: "
|
||||
"dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (*dest == '\0') {
|
||||
return (false);
|
||||
}
|
||||
|
||||
while (*dest && dmax) {
|
||||
|
||||
if ((*dest < 'a') || (*dest > 'z')) {
|
||||
return (false);
|
||||
}
|
||||
dest++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
EXPORT_SYMBOL(strislowercase_s)
|
|
@ -0,0 +1,120 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strismixedcase_s.c
|
||||
*
|
||||
* November 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011, 2013 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
|
||||
* strismixedcase_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* bool
|
||||
* strismixedcase_s(const char *dest, rsize_t dmax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function checks that the entire string is mixed
|
||||
* case. The scanning stops at the first null or after
|
||||
* dmax characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string
|
||||
*
|
||||
* dmax maximum length of string
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* true string is mixed case
|
||||
* false string is not mixed case or error
|
||||
*
|
||||
* ALSO SEE
|
||||
* strisalphanumeric_s(), strisascii_s(), strisdigit_s(),
|
||||
* strishex_s(), strislowercase_s(),
|
||||
* strisuppercase_s()
|
||||
*
|
||||
*/
|
||||
bool
|
||||
strismixedcase_s (const char *dest, rsize_t dmax)
|
||||
{
|
||||
if (!dest) {
|
||||
invoke_safe_str_constraint_handler("strismixedcase_s: "
|
||||
"dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strismixedcase_s: "
|
||||
"dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strismixedcase_s: "
|
||||
"dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (*dest == '\0') {
|
||||
return (false);
|
||||
}
|
||||
|
||||
while (*dest) {
|
||||
|
||||
if (((*dest >= 'a') && (*dest <= 'z')) ||
|
||||
((*dest >= 'A') && (*dest <= 'Z'))) {
|
||||
dest++;
|
||||
dmax--;
|
||||
} else {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
EXPORT_SYMBOL(strismixedcase_s)
|
|
@ -0,0 +1,169 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strispassword_s.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011, 2013 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
|
||||
* strispassword_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "strlib.h"
|
||||
* bool
|
||||
* strispassword_s(const char *dest, rsize_t dmax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function validates the make-up of a password string.
|
||||
* -SAFE_STR_PASSWORD_MIN_LENGTH character minimum
|
||||
* -SAFE_STR_PASSWORD_MAX_LENGTH character maximum
|
||||
* -at least SAFE_STR_MIN_LOWERCASE lower case characters
|
||||
* -at least SAFE_STR_MIN_UPPERCASE upper case characters
|
||||
* -at least SAFE_STR_MIN_NUMBERS number
|
||||
* -at least SAFE_STR_MIN_SPECIALS special
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string
|
||||
*
|
||||
* dmax length of password string
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* length > SAFE_STR_PASSWORD_MIN_LENGTH
|
||||
* length < SAFE_STR_PASSWORD_MAX_LENGTH
|
||||
* dest shall not be unterminated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* true, string has valid password makeup
|
||||
* false, string does not meet requirements or an error occurred
|
||||
*
|
||||
* ALSO SEE
|
||||
* strzero_s()
|
||||
*
|
||||
*/
|
||||
bool
|
||||
strispassword_s (const char *dest, rsize_t dmax)
|
||||
{
|
||||
uint32_t cnt_all;
|
||||
uint32_t cnt_lowercase;
|
||||
uint32_t cnt_uppercase;
|
||||
uint32_t cnt_numbers;
|
||||
uint32_t cnt_specials;
|
||||
|
||||
if (!dest) {
|
||||
invoke_safe_str_constraint_handler("strispassword_s: "
|
||||
"dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax < SAFE_STR_PASSWORD_MIN_LENGTH) {
|
||||
invoke_safe_str_constraint_handler("strispassword_s: "
|
||||
"dest is too short",
|
||||
NULL, ESLEMIN);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax > SAFE_STR_PASSWORD_MAX_LENGTH) {
|
||||
invoke_safe_str_constraint_handler("strispassword_s: "
|
||||
"dest exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (*dest == '\0') {
|
||||
return (false);
|
||||
}
|
||||
|
||||
cnt_all = cnt_lowercase = cnt_uppercase = 0;
|
||||
cnt_numbers = cnt_specials = 0;
|
||||
|
||||
while (*dest) {
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler(
|
||||
"strispassword_s: dest is unterminated",
|
||||
NULL, ESUNTERM);
|
||||
return (false);
|
||||
}
|
||||
dmax--;
|
||||
|
||||
cnt_all++;
|
||||
|
||||
if ((*dest >= '0') && (*dest <= '9')) {
|
||||
cnt_numbers++;
|
||||
|
||||
} else if ((*dest >= 'a') && (*dest <= 'z')) {
|
||||
cnt_lowercase++;
|
||||
|
||||
} else if ((*dest >= 'A') && (*dest <= 'Z')) {
|
||||
cnt_uppercase++;
|
||||
|
||||
/* allow all specials */
|
||||
} else if ((*dest >= 33) && (*dest <= 47)) {
|
||||
cnt_specials++;
|
||||
} else if ((*dest >= 58) && (*dest <= 64)) {
|
||||
cnt_specials++;
|
||||
} else if ((*dest >= 91) && (*dest <= 94)) {
|
||||
cnt_specials++;
|
||||
} else if ((*dest >= 95) && (*dest <= 96)) {
|
||||
cnt_specials++;
|
||||
} else if ((*dest >= 123) && (*dest <= 126)) {
|
||||
cnt_specials++;
|
||||
|
||||
} else {
|
||||
/* illegal char in password string */
|
||||
return (false);
|
||||
}
|
||||
dest++;
|
||||
}
|
||||
|
||||
if (cnt_all < SAFE_STR_PASSWORD_MAX_LENGTH &&
|
||||
cnt_numbers >= SAFE_STR_MIN_NUMBERS &&
|
||||
cnt_lowercase >= SAFE_STR_MIN_LOWERCASE &&
|
||||
cnt_uppercase >= SAFE_STR_MIN_UPPERCASE &&
|
||||
cnt_specials >= SAFE_STR_MIN_SPECIALS ) {
|
||||
return (true);
|
||||
} else {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(strispassword_s)
|
|
@ -0,0 +1,118 @@
|
|||
/*------------------------------------------------------------------
|
||||
* strisuppercase_s.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011, 2013 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
|
||||
* strisuppercase_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* bool
|
||||
* strisuppercase_s(const char *dest, rsize_t dmax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function checks if entire string is uppercase
|
||||
* The scanning stops at the first null or after dmax
|
||||
* characters.
|
||||
*
|
||||
* EXTENSION TO
|
||||
* ISO/IEC TR 24731, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to string
|
||||
*
|
||||
* dmax maximum length of string
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* dest shall not be a null pointer.
|
||||
* dmax shall not equal zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_STR.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* true string is uppercase
|
||||
* false string is not uppercase or an error occurred
|
||||
*
|
||||
* ALSO SEE
|
||||
* strisalphanumeric_s(), strisascii_s(), strisdigit_s(),
|
||||
* strishex_s(), strislowercase_s(), strismixedcase_s(),
|
||||
*
|
||||
*/
|
||||
bool
|
||||
strisuppercase_s (const char *dest, rsize_t dmax)
|
||||
{
|
||||
|
||||
if (!dest) {
|
||||
invoke_safe_str_constraint_handler("strisuppercase_s: "
|
||||
"dest is null",
|
||||
NULL, ESNULLP);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_str_constraint_handler("strisuppercase_s: "
|
||||
"dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_STR) {
|
||||
invoke_safe_str_constraint_handler("strisuppercase_s: "
|
||||
"dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (*dest == '\0') {
|
||||
return (false);
|
||||
}
|
||||
|
||||
while (*dest) {
|
||||
|
||||
if ((*dest < 'A') || (*dest > 'Z')) {
|
||||
return (false);
|
||||
}
|
||||
dest++;
|
||||
dmax--;
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
EXPORT_SYMBOL(strisuppercase_s)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue