mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-14 11:40:13 +01:00
44b7f056d9
bug1001332, 56b691c003ad, bug1086145, bug1054069, bug1155922, bug991783, bug1125025, bug1162521, bug1162644, bug1132941, bug1164364, bug1166205, bug1166163, bug1166515, bug1138554, bug1167046, bug1167043, bug1169451, bug1172128, bug1170322, bug102794, bug1128184, bug557830, bug1174648, bug1180244, bug1177784, bug1173413, bug1169174, bug1084669, bug951455, bug1183395, bug1177430, bug1183827, bug1160139, bug1154106, bug1142209, bug1185033, bug1193467, bug1182667(with sha512 changes backed out, which breaks VC6 compilation), bug1158489, bug337796
566 lines
16 KiB
C
566 lines
16 KiB
C
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
/*
|
|
* pkix_error.c
|
|
*
|
|
* Error Object Functions
|
|
*
|
|
*/
|
|
|
|
#include "pkix_error.h"
|
|
|
|
#undef PKIX_ERRORENTRY
|
|
|
|
#define PKIX_ERRORENTRY(name,desc,nsserr) #desc
|
|
|
|
#if defined PKIX_ERROR_DESCRIPTION
|
|
|
|
const char * const PKIX_ErrorText[] =
|
|
{
|
|
#include "pkix_errorstrings.h"
|
|
};
|
|
|
|
#else
|
|
|
|
#include "prprf.h"
|
|
|
|
#endif /* PKIX_ERROR_DESCRIPTION */
|
|
|
|
extern const PKIX_Int32 PKIX_PLErrorIndex[];
|
|
|
|
/* --Private-Functions-------------------------------------------- */
|
|
|
|
/*
|
|
* FUNCTION: pkix_Error_Equals
|
|
* (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
|
|
*/
|
|
static PKIX_Error *
|
|
pkix_Error_Equals(
|
|
PKIX_PL_Object *firstObject,
|
|
PKIX_PL_Object *secondObject,
|
|
PKIX_Boolean *pResult,
|
|
void *plContext)
|
|
{
|
|
PKIX_Error *firstError = NULL;
|
|
PKIX_Error *secondError = NULL;
|
|
PKIX_Error *firstCause = NULL;
|
|
PKIX_Error *secondCause = NULL;
|
|
PKIX_PL_Object *firstInfo = NULL;
|
|
PKIX_PL_Object *secondInfo = NULL;
|
|
PKIX_ERRORCLASS firstClass, secondClass;
|
|
PKIX_UInt32 secondType;
|
|
PKIX_Boolean boolResult, unequalFlag;
|
|
|
|
PKIX_ENTER(ERROR, "pkix_Error_Equals");
|
|
PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
|
|
|
|
unequalFlag = PKIX_FALSE;
|
|
|
|
/* First just compare pointer values to save time */
|
|
if (firstObject == secondObject) {
|
|
*pResult = PKIX_TRUE;
|
|
goto cleanup;
|
|
} else {
|
|
/* Result will only be set to true if all tests pass */
|
|
*pResult = PKIX_FALSE;
|
|
}
|
|
|
|
PKIX_CHECK(pkix_CheckType(firstObject, PKIX_ERROR_TYPE, plContext),
|
|
PKIX_FIRSTOBJECTNOTANERROROBJECT);
|
|
|
|
PKIX_CHECK(PKIX_PL_Object_GetType
|
|
(secondObject, &secondType, plContext),
|
|
PKIX_ERRORGETTINGSECONDOBJECTTYPE);
|
|
|
|
/* If types differ, then return false. Result is already set */
|
|
if (secondType != PKIX_ERROR_TYPE) goto cleanup;
|
|
|
|
/* It is safe to cast to PKIX_Error */
|
|
firstError = (PKIX_Error *) firstObject;
|
|
secondError = (PKIX_Error *) secondObject;
|
|
|
|
/* Compare error codes */
|
|
firstClass = firstError->errClass;
|
|
secondClass = secondError->errClass;
|
|
|
|
/* If codes differ, return false. Result is already set */
|
|
if (firstClass != secondClass) goto cleanup;
|
|
|
|
/* Compare causes */
|
|
firstCause = firstError->cause;
|
|
secondCause = secondError->cause;
|
|
|
|
/* Ensure that either both or none of the causes are NULL */
|
|
if (((firstCause != NULL) && (secondCause == NULL))||
|
|
((firstCause == NULL) && (secondCause != NULL)))
|
|
unequalFlag = PKIX_TRUE;
|
|
|
|
if ((firstCause != NULL) && (secondCause != NULL)) {
|
|
PKIX_CHECK(PKIX_PL_Object_Equals
|
|
((PKIX_PL_Object*)firstCause,
|
|
(PKIX_PL_Object*)secondCause,
|
|
&boolResult,
|
|
plContext),
|
|
PKIX_ERRORINRECURSIVEEQUALSCALL);
|
|
|
|
/* Set the unequalFlag so that we return after dec refing */
|
|
if (boolResult == 0) unequalFlag = PKIX_TRUE;
|
|
}
|
|
|
|
/* If the cause errors are not equal, return null */
|
|
if (unequalFlag) goto cleanup;
|
|
|
|
/* Compare info fields */
|
|
firstInfo = firstError->info;
|
|
secondInfo = secondError->info;
|
|
|
|
if (firstInfo != secondInfo) goto cleanup;
|
|
|
|
/* Ensure that either both or none of the infos are NULL */
|
|
if (((firstInfo != NULL) && (secondInfo == NULL))||
|
|
((firstInfo == NULL) && (secondInfo != NULL)))
|
|
unequalFlag = PKIX_TRUE;
|
|
|
|
if ((firstInfo != NULL) && (secondInfo != NULL)) {
|
|
|
|
PKIX_CHECK(PKIX_PL_Object_Equals
|
|
((PKIX_PL_Object*)firstInfo,
|
|
(PKIX_PL_Object*)secondInfo,
|
|
&boolResult,
|
|
plContext),
|
|
PKIX_ERRORINRECURSIVEEQUALSCALL);
|
|
|
|
/* Set the unequalFlag so that we return after dec refing */
|
|
if (boolResult == 0) unequalFlag = PKIX_TRUE;
|
|
}
|
|
|
|
/* If the infos are not equal, return null */
|
|
if (unequalFlag) goto cleanup;
|
|
|
|
|
|
/* Compare descs */
|
|
if (firstError->errCode != secondError->errCode) {
|
|
unequalFlag = PKIX_TRUE;
|
|
}
|
|
|
|
if (firstError->plErr != secondError->plErr) {
|
|
unequalFlag = PKIX_TRUE;
|
|
}
|
|
|
|
/* If the unequalFlag was set, return false */
|
|
if (unequalFlag) goto cleanup;
|
|
|
|
/* Errors are equal in all fields at this point */
|
|
*pResult = PKIX_TRUE;
|
|
|
|
cleanup:
|
|
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
/*
|
|
* FUNCTION: pkix_Error_Destroy
|
|
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
|
|
*/
|
|
static PKIX_Error *
|
|
pkix_Error_Destroy(
|
|
PKIX_PL_Object *object,
|
|
void *plContext)
|
|
{
|
|
PKIX_Error *error = NULL;
|
|
|
|
PKIX_ENTER(ERROR, "pkix_Error_Destroy");
|
|
PKIX_NULLCHECK_ONE(object);
|
|
|
|
PKIX_CHECK(pkix_CheckType(object, PKIX_ERROR_TYPE, plContext),
|
|
PKIX_OBJECTNOTANERROR);
|
|
|
|
error = (PKIX_Error *)object;
|
|
|
|
PKIX_DECREF(error->cause);
|
|
|
|
PKIX_DECREF(error->info);
|
|
|
|
cleanup:
|
|
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
|
|
/* XXX This is not thread safe */
|
|
static PKIX_UInt32 pkix_error_cause_depth = 1;
|
|
|
|
/*
|
|
* FUNCTION: pkix_Error_ToString
|
|
* (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
|
|
*/
|
|
static PKIX_Error *
|
|
pkix_Error_ToString(
|
|
PKIX_PL_Object *object,
|
|
PKIX_PL_String **pString,
|
|
void *plContext)
|
|
{
|
|
PKIX_Error *error = NULL;
|
|
PKIX_Error *cause = NULL;
|
|
PKIX_PL_String *desc = NULL;
|
|
PKIX_PL_String *formatString = NULL;
|
|
PKIX_PL_String *causeString = NULL;
|
|
PKIX_PL_String *optCauseString = NULL;
|
|
PKIX_PL_String *errorNameString = NULL;
|
|
char *format = NULL;
|
|
PKIX_ERRORCLASS errClass;
|
|
|
|
PKIX_ENTER(ERROR, "pkix_Error_ToString");
|
|
PKIX_NULLCHECK_TWO(object, pString);
|
|
|
|
PKIX_CHECK(pkix_CheckType(object, PKIX_ERROR_TYPE, plContext),
|
|
PKIX_OBJECTNOTANERROR);
|
|
|
|
error = (PKIX_Error *)object;
|
|
|
|
/* Get this error's errClass, description and the string of its cause */
|
|
errClass = error->errClass;
|
|
|
|
/* Get the description string */
|
|
PKIX_Error_GetDescription(error, &desc, plContext);
|
|
|
|
/* Get the cause */
|
|
cause = error->cause;
|
|
|
|
/* Get the causes's description string */
|
|
if (cause != NULL) {
|
|
pkix_error_cause_depth++;
|
|
|
|
/* Get the cause string */
|
|
PKIX_CHECK(PKIX_PL_Object_ToString
|
|
((PKIX_PL_Object*)cause, &causeString, plContext),
|
|
PKIX_ERRORGETTINGCAUSESTRING);
|
|
|
|
format = "\n*** Cause (%d): %s";
|
|
|
|
PKIX_CHECK(PKIX_PL_String_Create
|
|
(PKIX_ESCASCII,
|
|
format,
|
|
0,
|
|
&formatString,
|
|
plContext),
|
|
PKIX_STRINGCREATEFAILED);
|
|
|
|
/* Create the optional Cause String */
|
|
PKIX_CHECK(PKIX_PL_Sprintf
|
|
(&optCauseString,
|
|
plContext,
|
|
formatString,
|
|
pkix_error_cause_depth,
|
|
causeString),
|
|
PKIX_SPRINTFFAILED);
|
|
|
|
PKIX_DECREF(formatString);
|
|
|
|
pkix_error_cause_depth--;
|
|
}
|
|
|
|
/* Create the Format String */
|
|
if (optCauseString != NULL) {
|
|
format = "*** %s Error- %s%s";
|
|
} else {
|
|
format = "*** %s Error- %s";
|
|
}
|
|
|
|
/* Ensure that error errClass is known, otherwise default to Object */
|
|
if (errClass >= PKIX_NUMERRORCLASSES) {
|
|
errClass = 0;
|
|
}
|
|
|
|
PKIX_CHECK(PKIX_PL_String_Create
|
|
(PKIX_ESCASCII,
|
|
(void *)PKIX_ERRORCLASSNAMES[errClass],
|
|
0,
|
|
&errorNameString,
|
|
plContext),
|
|
PKIX_STRINGCREATEFAILED);
|
|
|
|
PKIX_CHECK(PKIX_PL_String_Create
|
|
(PKIX_ESCASCII,
|
|
format,
|
|
0,
|
|
&formatString,
|
|
plContext),
|
|
PKIX_STRINGCREATEFAILED);
|
|
|
|
/* Create the output String */
|
|
PKIX_CHECK(PKIX_PL_Sprintf
|
|
(pString,
|
|
plContext,
|
|
formatString,
|
|
errorNameString,
|
|
desc,
|
|
optCauseString),
|
|
PKIX_SPRINTFFAILED);
|
|
|
|
cleanup:
|
|
|
|
PKIX_DECREF(desc);
|
|
PKIX_DECREF(causeString);
|
|
PKIX_DECREF(formatString);
|
|
PKIX_DECREF(optCauseString);
|
|
PKIX_DECREF(errorNameString);
|
|
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
/*
|
|
* FUNCTION: pkix_Error_Hashcode
|
|
* (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
|
|
*/
|
|
static PKIX_Error *
|
|
pkix_Error_Hashcode(
|
|
PKIX_PL_Object *object,
|
|
PKIX_UInt32 *pResult,
|
|
void *plContext)
|
|
{
|
|
PKIX_ENTER(ERROR, "pkix_Error_Hashcode");
|
|
PKIX_NULLCHECK_TWO(object, pResult);
|
|
|
|
/* XXX Unimplemented */
|
|
/* XXX Need to make hashcodes equal when two errors are equal */
|
|
*pResult = (PKIX_UInt32)((char *)object - (char *)NULL);
|
|
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
/* --Initializers------------------------------------------------- */
|
|
|
|
/*
|
|
* PKIX_ERRORCLASSNAMES is an array of strings, with each string holding a
|
|
* descriptive name for an error errClass. This is used by the default
|
|
* PKIX_PL_Error_ToString function.
|
|
*
|
|
* Note: PKIX_ERRORCLASSES is defined in pkixt.h as a list of error types.
|
|
* (More precisely, as a list of invocations of ERRMACRO(type).) The
|
|
* macro is expanded in pkixt.h to define error numbers, and here to
|
|
* provide corresponding strings. For example, since the fifth ERRMACRO
|
|
* entry is MUTEX, then PKIX_MUTEX_ERROR is defined in pkixt.h as 4, and
|
|
* PKIX_ERRORCLASSNAMES[4] is initialized here with the value "MUTEX".
|
|
*/
|
|
#undef ERRMACRO
|
|
#define ERRMACRO(type) #type
|
|
|
|
const char *
|
|
PKIX_ERRORCLASSNAMES[PKIX_NUMERRORCLASSES] =
|
|
{
|
|
PKIX_ERRORCLASSES
|
|
};
|
|
|
|
/*
|
|
* FUNCTION: pkix_Error_RegisterSelf
|
|
* DESCRIPTION:
|
|
* Registers PKIX_ERROR_TYPE and its related functions with systemClasses[]
|
|
* THREAD SAFETY:
|
|
* Not Thread Safe - for performance and complexity reasons
|
|
*
|
|
* Since this function is only called by PKIX_PL_Initialize, which should
|
|
* only be called once, it is acceptable that this function is not
|
|
* thread-safe.
|
|
*/
|
|
PKIX_Error *
|
|
pkix_Error_RegisterSelf(void *plContext)
|
|
{
|
|
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
|
|
pkix_ClassTable_Entry entry;
|
|
|
|
PKIX_ENTER(ERROR, "pkix_Error_RegisterSelf");
|
|
|
|
entry.description = "Error";
|
|
entry.objCounter = 0;
|
|
entry.typeObjectSize = sizeof(PKIX_Error);
|
|
entry.destructor = pkix_Error_Destroy;
|
|
entry.equalsFunction = pkix_Error_Equals;
|
|
entry.hashcodeFunction = pkix_Error_Hashcode;
|
|
entry.toStringFunction = pkix_Error_ToString;
|
|
entry.comparator = NULL;
|
|
entry.duplicateFunction = pkix_duplicateImmutable;
|
|
|
|
systemClasses[PKIX_ERROR_TYPE] = entry;
|
|
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
/* --Public-Functions--------------------------------------------- */
|
|
|
|
/*
|
|
* FUNCTION: PKIX_Error_Create (see comments in pkix_util.h)
|
|
*/
|
|
PKIX_Error *
|
|
PKIX_Error_Create(
|
|
PKIX_ERRORCLASS errClass,
|
|
PKIX_Error *cause,
|
|
PKIX_PL_Object *info,
|
|
PKIX_ERRORCODE errCode,
|
|
PKIX_Error **pError,
|
|
void *plContext)
|
|
{
|
|
PKIX_Error *tempCause = NULL;
|
|
PKIX_Error *error = NULL;
|
|
|
|
PKIX_ENTER(ERROR, "PKIX_Error_Create");
|
|
|
|
PKIX_NULLCHECK_ONE(pError);
|
|
|
|
/*
|
|
* when called here, if PKIX_PL_Object_Alloc returns an error,
|
|
* it must be a PKIX_ALLOC_ERROR
|
|
*/
|
|
pkixErrorResult = PKIX_PL_Object_Alloc
|
|
(PKIX_ERROR_TYPE,
|
|
((PKIX_UInt32)(sizeof (PKIX_Error))),
|
|
(PKIX_PL_Object **)&error,
|
|
plContext);
|
|
|
|
if (pkixErrorResult) return (pkixErrorResult);
|
|
|
|
error->errClass = errClass;
|
|
|
|
/* Ensure we don't have a loop. Follow causes until NULL */
|
|
for (tempCause = cause;
|
|
tempCause != NULL;
|
|
tempCause = tempCause->cause) {
|
|
/* If we detect a loop, throw a new error */
|
|
if (tempCause == error) {
|
|
PKIX_ERROR(PKIX_LOOPOFERRORCAUSEDETECTED);
|
|
}
|
|
}
|
|
|
|
PKIX_INCREF(cause);
|
|
error->cause = cause;
|
|
|
|
PKIX_INCREF(info);
|
|
error->info = info;
|
|
|
|
error->errCode = errCode;
|
|
|
|
error->plErr = PKIX_PLErrorIndex[error->errCode];
|
|
|
|
*pError = error;
|
|
error = NULL;
|
|
|
|
cleanup:
|
|
/* PKIX-XXX Fix for leak during error creation */
|
|
PKIX_DECREF(error);
|
|
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
/*
|
|
* FUNCTION: PKIX_Error_GetErrorClass (see comments in pkix_util.h)
|
|
*/
|
|
PKIX_Error *
|
|
PKIX_Error_GetErrorClass(
|
|
PKIX_Error *error,
|
|
PKIX_ERRORCLASS *pClass,
|
|
void *plContext)
|
|
{
|
|
PKIX_ENTER(ERROR, "PKIX_Error_GetErrorClass");
|
|
PKIX_NULLCHECK_TWO(error, pClass);
|
|
|
|
*pClass = error->errClass;
|
|
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
/*
|
|
* FUNCTION: PKIX_Error_GetErrorCode (see comments in pkix_util.h)
|
|
*/
|
|
PKIX_Error *
|
|
PKIX_Error_GetErrorCode(
|
|
PKIX_Error *error,
|
|
PKIX_ERRORCODE *pCode,
|
|
void *plContext)
|
|
{
|
|
PKIX_ENTER(ERROR, "PKIX_Error_GetErrorCode");
|
|
PKIX_NULLCHECK_TWO(error, pCode);
|
|
|
|
*pCode = error->errCode;
|
|
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
/*
|
|
* FUNCTION: PKIX_Error_GetCause (see comments in pkix_util.h)
|
|
*/
|
|
PKIX_Error *
|
|
PKIX_Error_GetCause(
|
|
PKIX_Error *error,
|
|
PKIX_Error **pCause,
|
|
void *plContext)
|
|
{
|
|
PKIX_ENTER(ERROR, "PKIX_Error_GetCause");
|
|
PKIX_NULLCHECK_TWO(error, pCause);
|
|
|
|
if (error->cause != PKIX_ALLOC_ERROR()){
|
|
PKIX_INCREF(error->cause);
|
|
}
|
|
|
|
*pCause = error->cause;
|
|
|
|
cleanup:
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
/*
|
|
* FUNCTION: PKIX_Error_GetSupplementaryInfo (see comments in pkix_util.h)
|
|
*/
|
|
PKIX_Error *
|
|
PKIX_Error_GetSupplementaryInfo(
|
|
PKIX_Error *error,
|
|
PKIX_PL_Object **pInfo,
|
|
void *plContext)
|
|
{
|
|
PKIX_ENTER(ERROR, "PKIX_Error_GetSupplementaryInfo");
|
|
PKIX_NULLCHECK_TWO(error, pInfo);
|
|
|
|
PKIX_INCREF(error->info);
|
|
|
|
*pInfo = error->info;
|
|
|
|
cleanup:
|
|
PKIX_RETURN(ERROR);
|
|
}
|
|
|
|
/*
|
|
* FUNCTION: PKIX_Error_GetDescription (see comments in pkix_util.h)
|
|
*/
|
|
PKIX_Error *
|
|
PKIX_Error_GetDescription(
|
|
PKIX_Error *error,
|
|
PKIX_PL_String **pDesc,
|
|
void *plContext)
|
|
{
|
|
PKIX_PL_String *descString = NULL;
|
|
#ifndef PKIX_ERROR_DESCRIPTION
|
|
char errorStr[32];
|
|
#endif
|
|
|
|
PKIX_ENTER(ERROR, "PKIX_Error_GetDescription");
|
|
PKIX_NULLCHECK_TWO(error, pDesc);
|
|
|
|
#ifndef PKIX_ERROR_DESCRIPTION
|
|
PR_snprintf(errorStr, 32, "Error code: %d", error->errCode);
|
|
#endif
|
|
|
|
PKIX_PL_String_Create(PKIX_ESCASCII,
|
|
#if defined PKIX_ERROR_DESCRIPTION
|
|
(void *)PKIX_ErrorText[error->errCode],
|
|
#else
|
|
errorStr,
|
|
#endif
|
|
0,
|
|
&descString,
|
|
plContext);
|
|
|
|
*pDesc = descString;
|
|
|
|
PKIX_RETURN(ERROR);
|
|
}
|