static void skipSpace(char **pbp, char *endptr) { char *bp = *pbp; while (bp < endptr && OPTIONAL_SPACE(*bp)) { bp++; } *pbp = bp; }
/* Some characters must be escaped as a hex string, e.g. c -> \nn . * Others must be escaped by preceding with a '\', e.g. c -> \c , but * there are certain "special characters" that may be handled by either * escaping them, or by enclosing the entire attribute value in quotes. * A NULL value for pEQMode implies selecting minimalEscape mode. * Some callers will do quoting when needed, others will not. * If a caller selects minimalEscapeAndQuote, and the string does not * need quoting, then this function changes it to minimalEscape. */ static int cert_RFC1485_GetRequiredLen(const char *src, int srclen, EQMode *pEQMode) { int i, reqLen=0; EQMode mode = pEQMode ? *pEQMode : minimalEscape; PRBool needsQuoting = PR_FALSE; char lastC = 0; /* need to make an initial pass to determine if quoting is needed */ for (i = 0; i < srclen; i++) { char c = src[i]; reqLen++; if (NEEDS_HEX_ESCAPE(c)) { /* c -> \xx */ reqLen += 2; } else if (NEEDS_ESCAPE(c)) { /* c -> \c */ reqLen++; } else if (SPECIAL_CHAR(c)) { if (mode == minimalEscapeAndQuote) /* quoting is allowed */ needsQuoting = PR_TRUE; /* entirety will need quoting */ else if (mode == fullEscape) reqLen++; /* MAY escape this character */ } else if (OPTIONAL_SPACE(c) && OPTIONAL_SPACE(lastC)) { if (mode == minimalEscapeAndQuote) /* quoting is allowed */ needsQuoting = PR_TRUE; /* entirety will need quoting */ } lastC = c; } /* if it begins or ends in optional space it needs quoting */ if (!needsQuoting && srclen > 0 && mode == minimalEscapeAndQuote && (OPTIONAL_SPACE(src[srclen-1]) || OPTIONAL_SPACE(src[0]))) { needsQuoting = PR_TRUE; } if (needsQuoting) reqLen += 2; if (pEQMode && mode == minimalEscapeAndQuote && !needsQuoting) *pEQMode = minimalEscape; return reqLen; }
static SECStatus scanTag(const char **pbp, const char *endptr, char *tagBuf, int tagBufSize) { const char *bp; char *tagBufp; int taglen; PORT_Assert(tagBufSize > 0); /* skip optional leading space */ skipSpace(pbp, endptr); if (*pbp == endptr) { /* nothing left */ return SECFailure; } /* fill tagBuf */ taglen = 0; bp = *pbp; tagBufp = tagBuf; while (bp < endptr && !OPTIONAL_SPACE(*bp) && (*bp != C_EQUAL)) { if (++taglen >= tagBufSize) { *pbp = bp; return SECFailure; } *tagBufp++ = *bp++; } /* null-terminate tagBuf -- guaranteed at least one space left */ *tagBufp++ = 0; *pbp = bp; /* skip trailing spaces till we hit something - should be an equal sign */ skipSpace(pbp, endptr); if (*pbp == endptr) { /* nothing left */ return SECFailure; } if (**pbp != C_EQUAL) { /* should be an equal sign */ return SECFailure; } /* skip over the equal sign */ (*pbp)++; return SECSuccess; }
/* Returns the number of bytes in the value. 0 means failure. */ static int scanVal(char **pbp, char *endptr, char *valBuf, int valBufSize) { char *bp, *valBufp; int vallen = 0; PRBool isQuoted; PORT_Assert(valBufSize > 0); /* skip optional leading space */ skipSpace(pbp, endptr); if(*pbp == endptr) { /* nothing left */ return 0; } bp = *pbp; /* quoted? */ if (*bp == C_DOUBLE_QUOTE) { isQuoted = PR_TRUE; /* skip over it */ bp++; } else { isQuoted = PR_FALSE; } valBufp = valBuf; while (bp < endptr) { char c = *bp; if (c == C_BACKSLASH) { /* escape character */ bp++; if (bp >= endptr) { /* escape charater must appear with paired char */ *pbp = bp; return 0; } c = *bp; if (IS_HEX(c) && (endptr - bp) >= 2 && IS_HEX(bp[1])) { bp++; c = (char)((x2b[(PRUint8)c] << 4) | x2b[(PRUint8)*bp]); } } else if (c == '#' && bp == *pbp) { /* ignore leading #, quotation not required for it. */ } else if (!isQuoted && SPECIAL_CHAR(c)) { /* unescaped special and not within quoted value */ break; } else if (c == C_DOUBLE_QUOTE) { /* reached unescaped double quote */ break; } /* append character */ vallen++; if (vallen >= valBufSize) { *pbp = bp; return 0; } *valBufp++ = c; bp++; } /* strip trailing spaces from unquoted values */ if (!isQuoted) { while (valBufp > valBuf) { char c = valBufp[-1]; if (! OPTIONAL_SPACE(c)) break; --valBufp; } vallen = valBufp - valBuf; } if (isQuoted) { /* insist that we stopped on a double quote */ if (*bp != C_DOUBLE_QUOTE) { *pbp = bp; return 0; } /* skip over the quote and skip optional space */ bp++; skipSpace(&bp, endptr); } *pbp = bp; /* null-terminate valBuf -- guaranteed at least one space left */ *valBufp = 0; return vallen; }