📄 pgpprsasc.c
字号:
ptr[lineused] = temp_c;
*error = sendAnnotate (ctx, myself, PGPANN_CLEARDATA,
ctx->armorline, ctx->armorlen);
if (*error)
break;
ptr[lineused] = '\0';
}
/* skip the "whatever" in "-----BEGIN PGP whatever" */
while (isalnum (*ptr) || *ptr == ' ') {
ptr++;
lineused--;
}
/* check for multipart */
if (*ptr == ',') {
/* "-----BEGIN PGP whatever, PART x[/y]-----" */
if (memcmp (ptr, prefix2, sizeof (prefix2) - 1))
goto err_state_pgp_begin;
ptr += sizeof (prefix2) - 1;
lineused -= sizeof (prefix2) - 1;
thispart = strtoul ((char *)ptr, (char **)&num, 10);
if (num == NULL || thispart < 0 || thispart > 999)
goto err_state_pgp_begin;
lineused -= (num - ptr);
ptr = num;
/*
* now check for "/y", if it exists. It is
* legal for it not to exist, but it must have
* either a 'y' here or a messageID.
*/
if (*ptr == '/') {
maxparts = strtoul ((char *)ptr+1,
(char **)&num, 10);
if (!num || maxparts < 2 || maxparts > 999)
goto err_state_pgp_begin;
lineused -= (num - ptr);
ptr = num;
}
} else {
thispart = maxparts = 1;
}
if (memcmp (ptr, suffix, sizeof (suffix)))
goto err_state_pgp_begin;
ctx->thispart = thispart;
ctx->maxparts = maxparts;
goto state_pgp_end_anno;
err_state_pgp_begin:
ptr[lineused] = temp_c;
goto state_nonpgp;
case 100:
state_pgp_end_anno:
ctx->state = 100;
/* Send end-annotation (if we sent a begin annotation) */
if (ctx->annotation) {
pgpAssert (ctx->depth_at_ann == ctx->scope_depth);
*error = sendAnnotate (ctx, myself, ctx->annotation,
NULL, 0);
if (*error)
break;
ctx->annotation = 0;
}
/* FALLTHROUGH */
case 110:
state_pgp_armor_header:
ctx->state = 110;
/* read until EOL to get to end of the last line */
ctx->armorptr = ctx->armorline;
ctx->armorlen = 0;
while (ctx->eol != 1) {
ctx->armorlen = 0;
retval = readLine (ctx, buf, size);
written += retval;
buf += retval;
size -= retval;
if (!size)
return written;
}
ctx->eol = 0;
ctx->eob = 0;
ctx->armorlen = 0;
/* FALLTHROUGH */
case 120:
ctx->state = 120;
/* call readline until we have EOB or EOL */
retval = readLine (ctx, buf, size);
size -= retval;
buf += retval;
written += retval;
if (ctx->eol || ctx->eob)
;
else
break;
/* FALLTHROUGH */
case 125:
ctx->state = 125;
/* Send annotation of raw data if in passthrough mode */
if (ctx->passthrough) {
*error = sendAnnotate (ctx, myself, PGPANN_CLEARDATA,
ctx->armorline, ctx->armorlen);
if (*error)
break;
}
/* FALLTHROUGH */
case 130:
ctx->state = 130;
/*
* Process header line, then back to state armor_header,
* or detect end of headers, and go to state armor_nonheader.
*/
ptr = ctx->armorline;
lineused = ctx->armorlen;
/* Skip past prefix from "-----BEGIN PGP" if it matches */
if (ctx->skipPrefixLength > 0 &&
(PGPSize)lineused > ctx->skipPrefixLength &&
0 == memcmp (ptr, ctx->skipPrefix, ctx->skipPrefixLength)) {
ptr += ctx->skipPrefixLength;
lineused -= ctx->skipPrefixLength;
}
/* Find trailing white space... */
while (lineused && isspace (ptr[lineused - 1]))
lineused--;
ctx->noarmorblanks = FALSE;
if (lineused) {
int err;
/* temporarily null-terminate this string */
temp_c = ptr[lineused];
ptr[lineused] = '\0';
/*
* Change states once we see a non-header line. This is
* now the only way of changing to the state where we are
* parsing the ascii armor. It deals with the case where
* there are no blanks between the headers and the armored
* portion, as well as the normal case where there is a blank
* line, and also munging which inserts blank lines.
*/
if( validArmorLine( ptr, lineused ) ) {
ptr[lineused] = temp_c;
ctx->noarmorblanks = TRUE;
goto state_pgp_armor_nonheader;
}
err = parseHeader (ctx, ptr, lineused);
if (err) {
*error = sendAnnotate (ctx, myself,
PGPANN_ARMOR_BADHEADER,
ctx->armorline,
lineused);
ptr[lineused] = temp_c;
if (*error)
break;
/* XXX: Ignore bad headers? */
}
goto state_pgp_armor_header;
}
/*
* No longer change states on blank lines. Instead use
* the validArmorLine test above. This deals with the munging
* done by Eudora which makes every other line a blank line.
*/
goto state_pgp_armor_header;
/* Not reached */
/* FALLTHROUGH */
case 150:
state_pgp_armor_nonheader:
ctx->state = 150;
/* get the message and part information */
if (!ctx->part) {
/* This is true for all normal armor messages */
msg = getMessage (ctx, ctx->messageid, ctx->maxparts);
if (!msg) {
/* This is an error */
*error = kPGPError_OutOfMemory;
break;
}
part = getPart (ctx, msg, ctx->thispart);
if (!part) {
/* This is an error too */
*error = kPGPError_OutOfMemory;
break;
}
ctx->part = part;
}
ctx->expectcrc = 0;
/* FALLTHROUGH */
case 160:
ctx->state = 160;
/*
* Either try to make the message writable or send an
* annotation saying we have a message part.
*/
msg = ctx->part->msg;
if (ctx->thispart == 1) {
*error = writeMessage (ctx, msg);
if (*error)
break;
} else {
PGPByte *b;
b = (PGPByte *)pgpContextMemAlloc( cdkContext,
kPGPPrsAscCmdBufSize, kPGPMemoryMgrFlags_Clear);
if (b == NULL)
{
*error = kPGPError_OutOfMemory;
break;
}
i = 0;
memcpy (b, &ctx->thispart, sizeof (ctx->thispart));
i += sizeof (ctx->thispart);
memcpy (b+i, &ctx->maxparts, sizeof (ctx->maxparts));
i += sizeof (ctx->maxparts);
memcpy (b+i, ctx->messageid,
strlen (ctx->messageid));
i += strlen (ctx->messageid);
*error = sendAnnotate (ctx, myself, PGPANN_ARMOR_PART,
b, i);
pgpContextMemFree( cdkContext, b);
if (*error)
break;
}
/* If we had no blank lines, we already have an armor buffer */
if( ctx->noarmorblanks ) {
ctx->noarmorblanks = FALSE;
goto state_pgp_armor_line;
}
/* FALLTHROUGH */
case 170:
state_pgp_armor_loop:
ctx->state = 170;
/* read until EOL to get to end of the last line */
ctx->armorptr = ctx->armorline;
ctx->armorlen = 0;
while (ctx->eol != 1) {
ctx->armorlen = 0;
retval = readLine (ctx, buf, size);
written += retval;
buf += retval;
size -= retval;
if (!size)
return written;
}
ctx->eol = 0;
ctx->eob = 0;
ctx->armorlen = 0;
/* FALLTHROUGH */
case 180:
ctx->state = 180;
/* call readline until we have EOB or EOL */
retval = readLine (ctx, buf, size);
size -= retval;
buf += retval;
written += retval;
if (ctx->eol || ctx->eob)
;
else
break;
/* FALLTHROUGH */
case 185:
ctx->state = 185;
/* Send annotation of raw data if in passthrough mode */
if (ctx->passthrough) {
*error = sendAnnotate (ctx, myself, PGPANN_CLEARDATA,
ctx->armorline, ctx->armorlen);
if (*error)
break;
}
/* FALLTHROUGH */
case 190:
state_pgp_armor_line:
ctx->state = 190;
/*
* make sure this is not a CRC line. If it is a CRC
* then goto state armor_crc. if it is not a CRC line, then
* it must be an armorline. So, process it as an
* armor line and then fallthrough to next state to
* output it.
*/
ptr = ctx->armorline;
inlen = ctx->armorlen;
/* Skip past prefix from "-----BEGIN PGP" if it matches */
if (ctx->skipPrefixLength > 0 && inlen >= ctx->skipPrefixLength &&
0 == memcmp (ptr, ctx->skipPrefix, ctx->skipPrefixLength)) {
ptr += ctx->skipPrefixLength;
inlen -= ctx->skipPrefixLength;
}
if (ptr[0] == '=') {
/* This looks like a CRC */
goto state_pgp_armor_crc;
}
/* find the end of the armorline */
while (inlen && isspace (ptr[inlen - 1]))
inlen--;
/* check the length of the armorline */
if (inlen > 80) {
*error = sendAnnotate (ctx, myself,
PGPANN_ARMOR_TOOLONG,
ctx->armorline, ctx->armorlen);
if (*error)
break;
goto state_pgp_finish;
}
if (inlen == 0) {
/* Blank lines are just skipped, some mailers put blanks in */
goto state_pgp_armor_loop;
}
/* Make sure we're not expecting a CRC */
if (ctx->expectcrc) {
*error = sendAnnotate (ctx, myself, PGPANN_ARMOR_NOCRC,
ctx->armorline, ctx->armorlen);
if (*error)
break;
/* Well, maybe this is an end? */
goto state_pgp_armor_end;
}
if (inlen >= 9 && ptr[inlen-5] == '=') {
/* Handle CRC at end of armor line */
ctx->crcendline = TRUE;
i = pgpDearmorLine (ptr, ctx->databuf, inlen - 5);
} else {
i = pgpDearmorLine (ptr, ctx->databuf, inlen);
}
if (i < 1 || i > 60) {
/* error in deamorline */
*error = sendAnnotate (ctx, myself,
PGPANN_ARMOR_BADLINE,
ctx->armorline, ctx->armorlen);
if (*error)
break;
goto state_pgp_finish;
}
ctx->expectcrc = (i < 48);
ctx->crc = crcUpdate (ctx->crc, ctx->databuf, i);
ctx->datalen = i;
ctx->dataptr = ctx->databuf;
/* FALLTHROUGH */
case 200:
ctx->state = 200;
/* output the dearmored data, then goto state armor_loop */
/* But check for CRC on end of armor line and to armor_crc if so */
part = ctx->part;
while (ctx->datalen) {
retval = writePartData (part, ctx->dataptr,
ctx->datalen, error);
ctx->dataptr += retval;
ctx->datalen -= retval;
if (*error)
return written;
}
/* If had CRC at end of last armor line, go process it now */
if (ctx->crcendline) {
ctx->crcendline = FALSE;
goto state_pgp_armor_crc;
}
goto state_pgp_armor_loop;
case 210:
state_pgp_armor_crc:
ctx->state = 210;
/* Deal with CRC */
ptr = ctx->armorline;
inlen = ctx->armorlen;
/* Skip past prefix from "-----BEGIN PGP" if it matches */
if (ctx->skipPrefixLength > 0 && inlen >= ctx->skipPrefixLength &&
0 == memcmp (ptr, ctx->skipPrefix, ctx->skipPrefixLength)) {
ptr += ctx->skipPrefixLength;
inlen -= ctx->skipPrefixLength;
}
/* find the end of the armorline */
while (inlen && isspace (ptr[inlen - 1]))
inlen--;
if (ptr[0] != '=') {
/* Must be CRC at end of line */
pgpAssert(inlen >= 9 && ptr[inlen-5] == '=');
ptr += inlen - 5;
inlen = 5;
}
crc = dearmorCrc (ptr, inlen);
if (crc < 0) {
/* error */
*error = sendAnnotate (ctx, myself,
PGPANN_ARMOR_CRCCANT,
ctx->armorline, ctx->armorlen);
if (*error)
break;
goto state_pgp_finish;
}
if ((PGPUInt32)crc != ctx->crc) {
/* mismatch */
*error = sendAnnotate (ctx, myself,
PGPANN_ARMOR_CRCBAD,
ctx->armorline, ctx->armorlen);
if (*error)
break;
goto state_pgp_finish;
}
/* FALLTHROUGH */
case 220:
state_pgp_armor_end_loop:
ctx->state = 220;
/* read until EOL to get to end of the last line */
ctx->armorptr = ctx->armorline;
ctx->armorlen = 0;
whil
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -