mDNSlocal mDNSu8 *ConvertDigest(char *digest, int digestType, int *diglen) { int i, j; mDNSu8 *dig; switch (digestType) { case SHA1_DIGEST_TYPE: *diglen = CC_SHA1_DIGEST_LENGTH; break; case SHA256_DIGEST_TYPE: *diglen = CC_SHA256_DIGEST_LENGTH; break; default: LogMsg("ConvertDigest: digest type %d not supported", digestType); return mDNSNULL; } dig = mDNSPlatformMemAllocate(*diglen); if (!dig) { LogMsg("ConvertDigest: malloc failure"); return mDNSNULL; } for (j=0,i=0; i<*diglen*2; i+=2) { int l, h; l = HexVal(digest[i]); h = HexVal(digest[i+1]); if (l<0 || h<0) { LogMsg("ConvertDigest: Cannot convert digest"); return NULL;} dig[j++] = (mDNSu8)((l << 4) | h); } return dig; }
static void NumericConst (void) /* Parse a numeric constant */ { unsigned Base; /* Temporary number base */ unsigned Prefix; /* Base according to prefix */ StrBuf S = STATIC_STRBUF_INITIALIZER; int IsFloat; char C; unsigned DigitVal; unsigned long IVal; /* Value */ /* Check for a leading hex or octal prefix and determine the possible ** integer types. */ if (CurC == '0') { /* Gobble 0 and examine next char */ NextChar (); if (toupper (CurC) == 'X') { Base = Prefix = 16; NextChar (); /* gobble "x" */ } else { Base = 10; /* Assume 10 for now - see below */ Prefix = 8; /* Actual prefix says octal */ } } else { Base = Prefix = 10; } /* Because floating point numbers don't have octal prefixes (a number ** with a leading zero is decimal), we first have to read the number ** before converting it, so we can determine if it's a float or an ** integer. */ while (IsXDigit (CurC) && HexVal (CurC) < Base) { SB_AppendChar (&S, CurC); NextChar (); } SB_Terminate (&S); /* The following character tells us if we have an integer or floating ** point constant. Note: Hexadecimal floating point constants aren't ** supported in C89. */ IsFloat = (CurC == '.' || (Base == 10 && toupper (CurC) == 'E') || (Base == 16 && toupper (CurC) == 'P' && IS_Get (&Standard) >= STD_C99)); /* If we don't have a floating point type, an octal prefix results in an ** octal base. */ if (!IsFloat && Prefix == 8) { Base = 8; } /* Since we do now know the correct base, convert the remembered input ** into a number. */ SB_Reset (&S); IVal = 0; while ((C = SB_Get (&S)) != '\0') { DigitVal = HexVal (C); if (DigitVal >= Base) { Error ("Numeric constant contains digits beyond the radix"); } IVal = (IVal * Base) + DigitVal; } /* We don't need the string buffer any longer */ SB_Done (&S); /* Distinguish between integer and floating point constants */ if (!IsFloat) { unsigned Types; int HaveSuffix; /* Check for a suffix and determine the possible types */ HaveSuffix = 1; if (toupper (CurC) == 'U') { /* Unsigned type */ NextChar (); if (toupper (CurC) != 'L') { Types = IT_UINT | IT_ULONG; } else { NextChar (); Types = IT_ULONG; } } else if (toupper (CurC) == 'L') { /* Long type */ NextChar (); if (toupper (CurC) != 'U') { Types = IT_LONG | IT_ULONG; } else { NextChar (); Types = IT_ULONG; } } else { HaveSuffix = 0; if (Prefix == 10) { /* Decimal constants are of any type but uint */ Types = IT_INT | IT_LONG | IT_ULONG; } else { /* Octal or hex constants are of any type */ Types = IT_INT | IT_UINT | IT_LONG | IT_ULONG; } } /* Check the range to determine the type */ if (IVal > 0x7FFF) { /* Out of range for int */ Types &= ~IT_INT; /* If the value is in the range 0x8000..0xFFFF, unsigned int is not ** allowed, and we don't have a type specifying suffix, emit a ** warning, because the constant is of type long. */ if (IVal <= 0xFFFF && (Types & IT_UINT) == 0 && !HaveSuffix) { Warning ("Constant is long"); } } if (IVal > 0xFFFF) { /* Out of range for unsigned int */ Types &= ~IT_UINT; } if (IVal > 0x7FFFFFFF) { /* Out of range for long int */ Types &= ~IT_LONG; } /* Now set the type string to the smallest type in types */ if (Types & IT_INT) { NextTok.Type = type_int; } else if (Types & IT_UINT) { NextTok.Type = type_uint; } else if (Types & IT_LONG) { NextTok.Type = type_long; } else { NextTok.Type = type_ulong; } /* Set the value and the token */ NextTok.IVal = IVal; NextTok.Tok = TOK_ICONST; } else { /* Float constant */ Double FVal = FP_D_FromInt (IVal); /* Convert to double */ /* Check for a fractional part and read it */ if (CurC == '.') { Double Scale; /* Skip the dot */ NextChar (); /* Read fractional digits */ Scale = FP_D_Make (1.0); while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) { /* Get the value of this digit */ Double FracVal = FP_D_Div (FP_D_FromInt (DigitVal * Base), Scale); /* Add it to the float value */ FVal = FP_D_Add (FVal, FracVal); /* Scale base */ Scale = FP_D_Mul (Scale, FP_D_FromInt (DigitVal)); /* Skip the digit */ NextChar (); } } /* Check for an exponent and read it */ if ((Base == 16 && toupper (CurC) == 'F') || (Base == 10 && toupper (CurC) == 'E')) { unsigned Digits; unsigned Exp; /* Skip the exponent notifier */ NextChar (); /* Read an optional sign */ if (CurC == '-') { NextChar (); } else if (CurC == '+') { NextChar (); } /* Read exponent digits. Since we support only 32 bit floats ** with a maximum exponent of +-/127, we read the exponent ** part as integer with up to 3 digits and drop the remainder. ** This avoids an overflow of Exp. The exponent is always ** decimal, even for hex float consts. */ Digits = 0; Exp = 0; while (IsDigit (CurC)) { if (++Digits <= 3) { Exp = Exp * 10 + HexVal (CurC); } NextChar (); } /* Check for errors: We must have exponent digits, and not more ** than three. */ if (Digits == 0) { Error ("Floating constant exponent has no digits"); } else if (Digits > 3) { Warning ("Floating constant exponent is too large"); } /* Scale the exponent and adjust the value accordingly */ if (Exp) { FVal = FP_D_Mul (FVal, FP_D_Make (pow (10, Exp))); } } /* Check for a suffix and determine the type of the constant */ if (toupper (CurC) == 'F') { NextChar (); NextTok.Type = type_float; } else { NextTok.Type = type_double; } /* Set the value and the token */ NextTok.FVal = FVal; NextTok.Tok = TOK_FCONST; } }
static int ParseChar (StrBuf* B) /* Parse a character. Converts \n into EOL, etc. */ { unsigned I; unsigned Val; int C; /* Check for escape chars */ if ((C = SB_Get (B)) == '\\') { switch (SB_Peek (B)) { case '?': C = '?'; SB_Skip (B); break; case 'a': C = '\a'; SB_Skip (B); break; case 'b': C = '\b'; SB_Skip (B); break; case 'f': C = '\f'; SB_Skip (B); break; case 'r': C = '\r'; SB_Skip (B); break; case 'n': C = '\n'; SB_Skip (B); break; case 't': C = '\t'; SB_Skip (B); break; case 'v': C = '\v'; SB_Skip (B); break; case '\"': C = '\"'; SB_Skip (B); break; case '\'': C = '\''; SB_Skip (B); break; case '\\': C = '\\'; SB_Skip (B); break; case 'x': case 'X': /* Hex character constant */ SB_Skip (B); C = HexVal (SB_Get (B)) << 4; C |= HexVal (SB_Get (B)); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': /* Octal constant */ I = 0; Val = SB_Get (B) - '0'; while (SB_Peek (B) >= '0' && SB_Peek (B) <= '7' && ++I <= 3) { Val = (Val << 3) | (SB_Get (B) - '0'); } C = (int) Val; if (Val > 256) { Error ("Character constant out of range"); C = ' '; } break; default: Error ("Illegal character constant 0x%02X", SB_Get (B)); C = ' '; break; } } /* Return the character */ return C; }
static int ParseChar (void) /* Parse a character. Converts escape chars into character codes. */ { int C; int HadError; int Count; /* Check for escape chars */ if (CurC == '\\') { NextChar (); switch (CurC) { case '?': C = '\?'; break; case 'a': C = '\a'; break; case 'b': C = '\b'; break; case 'f': C = '\f'; break; case 'r': C = '\r'; break; case 'n': C = '\n'; break; case 't': C = '\t'; break; case 'v': C = '\v'; break; case '\"': C = '\"'; break; case '\'': C = '\''; break; case '\\': C = '\\'; break; case 'x': case 'X': /* Hex character constant */ if (!IsXDigit (NextC)) { Error ("\\x used with no following hex digits"); C = ' '; } else { HadError = 0; C = 0; while (IsXDigit (NextC)) { if ((C << 4) >= 256) { if (!HadError) { Error ("Hex character constant out of range"); HadError = 1; } } else { C = (C << 4) | HexVal (NextC); } NextChar (); } } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': /* Octal constant */ Count = 1; C = HexVal (CurC); while (IsODigit (NextC) && Count++ < 3) { C = (C << 3) | HexVal (NextC); NextChar (); } if (C >= 256) Error ("Octal character constant out of range"); break; default: C = CurC; Error ("Illegal escaped character: 0x%02X", CurC); break; } } else { C = CurC; } /* Skip the character read */ NextChar (); /* Do correct sign extension */ return SignExtendChar (C); }
int SB_GetNumber (StrBuf* B, long* Val) /* Get a number from the string buffer. Accepted formats are decimal, octal, ** hex and character constants. Numeric constants may be preceeded by a ** minus or plus sign. The function returns 1 if a number was found and ** zero otherwise. Errors are only output for invalid numbers. */ { int Sign; char C; unsigned Base; unsigned DigitVal; /* Initialize Val */ *Val = 0; /* Handle character constants */ if (SB_Peek (B) == '\'') { /* Character constant */ SB_Skip (B); *Val = SignExtendChar (TgtTranslateChar (ParseChar (B))); if (SB_Peek (B) != '\'') { Error ("`\'' expected"); return 0; } else { /* Skip the quote */ SB_Skip (B); return 1; } } /* Check for a sign. A sign must be followed by a digit, otherwise it's ** not a number */ Sign = 1; switch (SB_Peek (B)) { case '-': Sign = -1; /* FALLTHROUGH */ case '+': if (!IsDigit (SB_LookAt (B, SB_GetIndex (B) + 1))) { return 0; } SB_Skip (B); break; } /* We must have a digit now, otherwise its not a number */ C = SB_Peek (B); if (!IsDigit (C)) { return 0; } /* Determine the base */ if (C == '0') { /* Hex or octal */ SB_Skip (B); if (tolower (SB_Peek (B)) == 'x') { SB_Skip (B); Base = 16; if (!IsXDigit (SB_Peek (B))) { Error ("Invalid hexadecimal number"); return 0; } } else { Base = 8; } } else { Base = 10; } /* Read the number */ while (IsXDigit (C = SB_Peek (B)) && (DigitVal = HexVal (C)) < Base) { *Val = (*Val * Base) + DigitVal; SB_Skip (B); } /* Allow optional 'U' and 'L' modifiers */ C = SB_Peek (B); if (C == 'u' || C == 'U') { SB_Skip (B); C = SB_Peek (B); if (C == 'l' || C == 'L') { SB_Skip (B); } } else if (C == 'l' || C == 'L') { SB_Skip (B); C = SB_Peek (B); if (C == 'u' || C == 'U') { SB_Skip (B); } } /* Success, value read is in Val */ *Val *= Sign; return 1; }