📄 pgpdebug.c
字号:
/*____________________________________________________________________________
pgpDebug.c
Copyright (C) 1996,1997 Network Associates Inc. and affiliated companies.
All rights reserved.
Assertion support routines
$Id: pgpDebug.c,v 1.5 1999/03/10 02:49:24 heller Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h"
#include <stdarg.h>
#include <limits.h>
#include "pgpTypes.h"
#include "pgpDebug.h"
#include "pgpMem.h"
#if PGP_DEBUG && !PGP_DEBUG_STACK_BUFFERS
uchar pgpaDebugBuf[PGP_DEBUG_BUF_SIZE * PGP_DEBUG_NUM_BUFS];
uchar * pgpaDebugBufStack = pgpaDebugBuf + sizeof(pgpaDebugBuf);
#endif
static PGPSize sStrLen(const char *buffer)
{
PGPSize count = 0;
if (IsNull(buffer))
return 0;
while (buffer[count] != '\0')
count++;
return count;
}
static void
AppendChars(
uchar * dest,
int * offset,
int max,
PGPBoolean canonicalizeNLs,
char const * src,
int len)
{
int destIndex = *offset;
int srcIndex = 0;
pgpa(pgpaAddrValid(src, char));
if (canonicalizeNLs)
{
while (srcIndex < len && destIndex < max)
switch (src[srcIndex])
{
case '\r':
if (srcIndex + 1 < len && src[srcIndex + 1] == '\n')
srcIndex++;
/* Fall through */
case '\n':
#if PGP_MACINTOSH
dest[destIndex++] = '\r';
#elif defined(PGP_WIN32)
dest[destIndex++] = '\r';
if (destIndex < max)
dest[destIndex++] = '\n';
#else
dest[destIndex++] = '\n';
#endif
srcIndex++;
break;
default:
dest[destIndex++] = src[srcIndex++];
break;
}
}
else
{
while (srcIndex < len && destIndex < max)
dest[destIndex++] = src[srcIndex++];
}
*offset = destIndex;
}
static void
AppendUnsignedNumber(
uchar * dest,
int * offset,
int max,
int radix,
PGPUInt32 num)
{
static char const digit[17] = "0123456789ABCDEF";
char buf[36];
int i = sizeof(buf);
pgpAssertMsg(radix >= 2 && radix <= 16, "Invalid radix");
do
{
pgpAssert(i > 0);
buf[--i] = digit[num % radix];
num /= radix;
} while (num > 0);
AppendChars(dest, offset, max, FALSE, buf + i, sizeof(buf) - i);
}
static void
AppendSignedNumber(
uchar * dest,
int * offset,
int max,
int radix,
long num)
{
if (num < 0)
{
AppendChars(dest, offset, max, FALSE, "-", 1);
AppendUnsignedNumber(dest, offset, max, radix, -num);
}
else
AppendUnsignedNumber(dest, offset, max, radix, num);
}
/*
* Formats a string into the given <buffer>, similarly to sprintf.
* If <putLengthPrefix> is true, a pascal-style length prefix is put at the
* beginning of the string. If <putNullTerminator> is true, a 0 byte is
* added to the end. This allows creation of C strings, Pascal strings, or
* hybrid strings which are both. <bufferSize> indicates the size of the
* buffer, ie, the total number of bytes which can be modified, including
* length prefix size and null-terminator. In all cases, the length of the
* string in actual characters is returned.
*
* Recognizes the following special sequences in the format string:
* %% Replaced with a single '%'
* %c Replaced with the char argument
* %s Replaced with the C string argument
* %S Replaced with the Pascal string argument
* %B Replaced with the memory buffer as a string
* (two args: length (int), buffer)
* %lB Replaced with the memory buffer as a string
* (two args: length (long), buffer)
* %d Replaced with the signed integer value (base 10)
* %ld Replaced with the signed long value (base 10)
* %u Replaced with the unsigned integer value (base 10)
* %lu Replaced with the unsigned long value (base 10)
* %x Replaced with the unsigned integer value (base 16)
* %lx Replaced with the unsigned long value (base 16)
* %o Replaced with the unsigned integer value (base 8)
* %lo Replaced with the unsigned long value (base 8)
* %b Replaced with the unsigned integer value (base 2)
* %lb Replaced with the unsigned long value (base 2)
* %p Replaced with the pointer value, printed in hex
*/
int
pgpFormatVAStr(
uchar * buffer,
int bufferSize,
PGPBoolean putLengthPrefix,
PGPBoolean putNullTerminator,
PGPBoolean canonicalizeNLs,
char const * formatStr,
va_list args)
{
int bufferIndex = putLengthPrefix ? 1 : 0;
int formatStrIndex;
int stringLength;
pgpa((
pgpaAddrValid(buffer, uchar),
pgpaAssert(bufferSize >=
putLengthPrefix + (putNullTerminator ? 1 : 0)),
pgpaAddrValid(formatStr, char),
pgpaMsg("Invalid parameters to pgpaFormatVAStr")));
for (formatStrIndex = 0; formatStr[formatStrIndex] != '\0';
formatStrIndex++)
{
if (formatStr[formatStrIndex] != '%')
AppendChars(buffer, &bufferIndex, bufferSize,
canonicalizeNLs, &formatStr[formatStrIndex], 1);
else if (formatStr[formatStrIndex + 1] != '\0')
{
int cmdStartIndex = formatStrIndex;
PGPBoolean longFlag = FALSE;
int radix;
formatStrIndex++;
if (formatStr[formatStrIndex] == 'l')
{
longFlag = TRUE;
formatStrIndex++;
}
switch (formatStr[formatStrIndex])
{
case '%': /* Literal '%' */
AppendChars(buffer, &bufferIndex, bufferSize,
FALSE, &formatStr[formatStrIndex], 1);
break;
case 'c': /* Single character */
{
char ch = va_arg(args, char);
AppendChars(buffer, &bufferIndex, bufferSize,
canonicalizeNLs, &ch, 1);
break;
}
case 's': /* C string argument */
{
char const * str = va_arg(args, char const *);
pgpa(pgpaAddrValid(str, char));
AppendChars(buffer, &bufferIndex, bufferSize,
canonicalizeNLs, str, sStrLen(str));
break;
}
case 'S': /* Pascal string argument */
{
uchar const * pstr = va_arg(args, uchar const *);
pgpa(pgpaAddrValid(pstr, uchar));
AppendChars(buffer, &bufferIndex, bufferSize,
canonicalizeNLs, (char *)(pstr + 1), pstr[0]);
break;
}
case 'B': /* String buffer argument (length, buf) */
{
long length;
char const * buf;
if (longFlag)
length = va_arg(args, long);
else
length = va_arg(args, int);
buf = va_arg(args, char const *);
pgpa((
pgpaAssert(length >= 0),
pgpaAddrValid(buf, char)));
if (length > INT_MAX)
length = INT_MAX;
AppendChars(buffer, &bufferIndex, bufferSize,
canonicalizeNLs, buf, length);
break;
}
case 'p': /* pointer argument */
pgpAssert(sizeof(PGPUInt32) == sizeof(void *));
AppendChars(buffer, &bufferIndex, bufferSize,
FALSE, "0x", 2);
longFlag = TRUE;
radix = 16;
goto doUInt;
case 'x': /* unsigned int argument, base 16 */
case 'X':
radix = 16;
goto doUInt;
case 'o': /* unsigned int argument, base 8 */
radix = 8;
goto doUInt;
case 'b': /* unsigned int argument, base 2 */
radix = 2;
goto doUInt;
case 'u': /* unsigned int argument, base 10 */
radix = 10;
doUInt:
{
PGPUInt32 num;
if (longFlag)
num = va_arg(args, PGPUInt32);
else
num = va_arg(args, unsigned int);
AppendUnsignedNumber(buffer, &bufferIndex, bufferSize,
radix, num);
}
break;
case 'd': /* signed integer argument, base 10 */
{
long num;
if (longFlag)
num = va_arg(args, long);
else
num = va_arg(args, int);
AppendSignedNumber(buffer, &bufferIndex, bufferSize,
10, num);
break;
}
default:
{
char errorBuf[32];
pgpFormatStr(errorBuf, sizeof(errorBuf), FALSE,
"[INVALID %B]",
formatStrIndex - cmdStartIndex + 1,
formatStr + cmdStartIndex);
AppendChars(buffer, &bufferIndex, bufferSize,
canonicalizeNLs, errorBuf, sStrLen(errorBuf));
break;
}
}
}
}
if (putNullTerminator)
{
if (bufferIndex >= bufferSize)
bufferIndex = bufferSize - 1;
buffer[bufferIndex] = '\0';
}
stringLength = bufferIndex - (putLengthPrefix ? 1 : 0);
if (putLengthPrefix)
buffer[0] = (stringLength <= 255) ? stringLength : 255;
return stringLength;
}
uchar *
pgpFormatHStr(
uchar * buffer,
int bufferSize,
PGPBoolean canonicalizeNLs,
char const * formatStr,
...)
{
va_list args;
va_start(args, formatStr);
pgpFormatVAStr(buffer, bufferSize, TRUE, TRUE, canonicalizeNLs,
formatStr, args);
va_end(args);
return buffer;
}
uchar *
pgpFormatPStr(
uchar * buffer,
int bufferSize,
PGPBoolean canonicalizeNLs,
char const * formatStr,
...)
{
va_list args;
va_start(args, formatStr);
pgpFormatVAStr(buffer, bufferSize, TRUE, FALSE, canonicalizeNLs,
formatStr, args);
va_end(args);
return buffer;
}
uchar *
pgpFormatPStr255(
uchar * buffer,
PGPBoolean canonicalizeNLs,
char const * formatStr,
...)
{
va_list args;
va_start(args, formatStr);
pgpFormatVAStr(buffer, 256, TRUE, FALSE, canonicalizeNLs, formatStr, args);
va_end(args);
return buffer;
}
char *
pgpFormatStr(
char * buffer,
int bufferSize,
PGPBoolean canonicalizeNLs,
char const * formatStr,
...)
{
va_list args;
va_start(args, formatStr);
pgpFormatVAStr((uchar *)buffer, bufferSize, FALSE, TRUE, canonicalizeNLs,
formatStr, args);
va_end(args);
return buffer;
}
#if PGP_DEBUG /* [ */
uchar *
pgpDebugFormatHStr(
uchar * buffer,
int bufferSize,
char const * formatStr,
...)
{
va_list args;
va_start(args, formatStr);
pgpFormatVAStr(buffer, bufferSize, TRUE, TRUE, TRUE, formatStr, args);
va_end(args);
return buffer;
}
uchar *
pgpDebugPrefixFormatHStr(
uchar * buffer,
int bufferSize,
char const * formatStr,
...)
{
va_list args;
int origSize; /* Including null, but not length prefix */
int origOffset;
int prefixSize; /* Including length prefix, no null */
int totalLen;
/*
* Move the original string (except length prefix) to the end of the
* buffer.
*/
origSize = buffer[0] + 1;
if (origSize == 256)
origSize = sStrLen((char const *)buffer + 1) + 1;
origOffset = bufferSize - origSize;
pgpCopyMemory(buffer + 1, buffer + origOffset, origSize);
/* Format the new prefix, without null-terminator */
va_start(args, formatStr);
prefixSize = 1 + pgpFormatVAStr(buffer, origOffset, TRUE, FALSE, TRUE,
formatStr, args);
va_end(args);
/* Add a separating string */
AppendChars(buffer, &prefixSize, origOffset, TRUE, ":\n ", 4);
/* Move the original part back so that it's adjacent to the prefix */
pgpCopyMemory(buffer + origOffset, buffer + prefixSize, origSize);
/* Set the length prefix */
totalLen = (origSize - 1) + (prefixSize - 1);
buffer[0] = (totalLen <= 255) ? totalLen : 255;
return buffer;
}
void
pgpDebugFillMemory(
void * buffer,
size_t length)
{
pgpFillMemory(buffer, length, 0xDD);
}
static char
pgpMemAccessTest(
void const * addr)
{
return *(volatile char const *)addr;
}
PGPBoolean
pgpaInternalAddrValid(
pgpaCallPrefixDef,
void const * addr,
int alignSize,
char const * varName)
{
#if PGP_MACINTOSH
/* XXX alignof() doesn't match up with reality...bummer */
if (alignSize > 2)
alignSize = 2;
#endif
pgpaAssert(addr != NULL);
pgpaAssert(alignSize > 0);
pgpaAssert(alignSize == 1 || (PGPUInt32)addr % alignSize == 0);
#if PGP_MACINTOSH
pgpaAssert((PGPUInt32)addr >= 256);
#endif
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaAddrValidAligned failed on %s (%p) (align %d)",
varName, addr, alignSize));
if (!pgpaFailed)
pgpMemAccessTest(addr);
return pgpaFailed;
}
PGPBoolean
pgpaInternalStrLenValid(
pgpaCallPrefixDef,
char const * str,
PGPUInt32 minLen,
PGPUInt32 maxLen,
char const * varName)
{
PGPUInt32 i;
pgpaAddrValid(str, char);
for (i = 0; !pgpaFailed && str[i] != '\0'; i++)
{
pgpaFailIf(i >= maxLen, (pgpaFmtPrefix,
"longer than %lu chars", maxLen));
pgpaFailIf((uchar)(str[i]) < '\b', (pgpaFmtPrefix,
"suspicious char 0x%x at index %lu", str[i], i));
}
pgpaFailIf(i < minLen, (pgpaFmtPrefix, "shorter than %lu chars", minLen));
pgpaFmtMsg((pgpaFmtPrefix, "pgpaStrLenValid failed on %s (%p)",
varName, str));
return pgpaFailed;
}
PGPBoolean
pgpaInternalPStrLenValid(
pgpaCallPrefixDef,
uchar const * str,
int minLen,
int maxLen,
char const * varName)
{
int len;
int i;
pgpaAssert(minLen >= 0),
pgpaAssert(maxLen <= 255),
pgpaAddrValid(str, uchar);
if (!pgpaFailed)
{
len = str[0];
pgpaFailIf(len > maxLen, (pgpaFmtPrefix,
"longer than %d chars", maxLen));
pgpaFailIf(len < minLen, (pgpaFmtPrefix,
"shorter than %d chars", minLen));
for (i = 1; !pgpaFailed && i <= len; i++)
pgpaFailIf(str[i] < '\b', (pgpaFmtPrefix,
"suspicious char 0x%x at index %d", str[i], i));
pgpaFailIf(i < minLen, (pgpaFmtPrefix,
"shorter than %lu chars", minLen));
}
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaPStrLenValid failed on %s (%p)", varName, str));
return pgpaFailed;
}
void
pgpDebugHook(void)
{
}
#endif /* ] PGP_DEBUG */
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -