/* DoParsePart (static) * * Private function used to pipe the output of 1847 parsing into a file. */ static int DoParsePart(BufTypePtr pInBuf, FILE *fOut, emsMIMEtypeP *mimePtr, int bDeMime, PartParseStatePtr pState) { if (!pInBuf) // Input buf NULL indicates 'cleanup' { if (!pState->bFoundHeader) return (FALSE); else return (TRUE); } if (!pState->bFoundHeader) { resetpos_buf(pState->pSearchBuf); if (pState->nPrevEndMatch > 0) { /* Check for completion of span */ // If doesn't continue match, returns zero // otherwise returns number of chars of pSearchBuf that have been matched unsigned int nNewMatched = completecount_buf(pInBuf, pState->pSearchBuf, pState->nPrevEndMatch); if (nNewMatched == buflen_buf(pState->pSearchBuf)) /* complete match made */ { pState->bFoundHeader = TRUE; pState->nPrevEndMatch = 0; bufncat_buf(pState->pBuf, pInBuf, (buflen_buf(pState->pSearchBuf) - (pState->nPrevEndMatch))); } else if (nNewMatched != 0) /* Continued to match, but not completed yet -- the input buffer is smaller than the pSearchBuf */ { bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf)); pState->nPrevEndMatch = nNewMatched; return (TRUE); } else /* No match continuation */ { pState->nPrevEndMatch = 0; } } resetpos_buf(pState->pSearchBuf); // Still not found -- no span if (!pState->bFoundHeader) { // Find match of pSearchBuf, either complete or end-spanning // return number of chars to skip before match unsigned int nSkip = skipcount_buf(pInBuf, pState->pSearchBuf); unsigned int nRemain = poslen_buf(pInBuf) - nSkip; if (nRemain == 0) // Not found { bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf)); return (TRUE); } else if (nRemain > buflen_buf(pState->pSearchBuf)) /* Found 'complete' */ { pState->bFoundHeader = TRUE; bufncat_buf(pState->pBuf, pInBuf, (nSkip + buflen_buf(pState->pSearchBuf)) ); } else // Partial possible { pState->nPrevEndMatch = nRemain; bufncat_buf(pState->pBuf, pInBuf, poslen_buf(pInBuf)); return (TRUE); } } // ---------- Now we know it is found ---------- unsigned int nLen = buflen_buf(pState->pBuf); char *pHeader = (char *) malloc(nLen + 1); strncpy(pHeader, getbuf_buf(pState->pBuf), nLen); { char *pCT = rfc822_extract_header(pHeader, "Content-Type:"); if (mimePtr) { if (pCT) { *mimePtr = parse_make_mime_type(pCT); } else { *mimePtr = make_mime_type("text", "plain", "1.0"); } } safefree(pCT); } if (bDeMime) { { char *pCTE = rfc822_extract_cte(pHeader); if (pCTE) pState->cte = rfc822_parse_cte(pCTE); else pState->cte = CTE_NONE; /* No CTE header, so no encoding */ safefree(pCTE); } switch (pState->cte) { // BASE64 case CTE_Base64: { // BASE64 expands about 1/3 unsigned int preEncBufLen = ((kBufferSize * 10) / 6); pState->preEncBuffer = (char *) malloc(preEncBufLen); pState->d64state = (Dec64Ptr) malloc(sizeof(Dec64)); // Used by Decode64() pState->d64state->decoderState = 0; pState->d64state->invalCount = 0; pState->d64state->padCount = 0; pState->d64state->partial = 0; pState->d64state->wasCR = FALSE; } break; // QUOTED-PRINTABLE case CTE_QP: { // QP expands max of 3 times unsigned int preEncBufLen = (kBufferSize * 4); pState->preEncBuffer = (char *) malloc(preEncBufLen); pState->dQPstate = (DecQPPtr) malloc(sizeof(EncQP)); pState->dQPstate->CurState = qpNormal; pState->dQPstate->cLastChar = 0; } break; // Otherwise, no encoding default: break; } } else { fwrite(getbuf_buf(pState->pBuf), sizeof(char), nLen, fOut); } safefree(pHeader) free_buf(pState->pBuf); } // ---------- Now we know it is found and header is init'd ---------- long errorcnt; switch (pState->cte) { case CTE_Base64: { unsigned int nReadLen = Decode64(getpos_buf(pInBuf), poslen_buf(pInBuf), pState->preEncBuffer, pState->d64state, &errorcnt); fwrite(pState->preEncBuffer, sizeof(char), nReadLen, fOut); } break; case CTE_QP: { unsigned int nReadLen = DecodeQP(getpos_buf(pInBuf), poslen_buf(pInBuf), pState->preEncBuffer, pState->dQPstate, &errorcnt); fwrite(pState->preEncBuffer, sizeof(char), nReadLen, fOut); } break; default: /* 7bit, 8bit, binary, none */ { fwrite(getpos_buf(pInBuf), sizeof(char), poslen_buf(pInBuf), fOut); } break; } return (TRUE); }
BOOL CMime::DecodeBlock(LPMIMEBLOCK pmb) {_STT(); // Is it already decoded? if ( ( pmb->f1 & MBF1_DECODED ) != 0 ) return TRUE; // If base64 encoded if ( ( pmb->encode & MBEN_BASE64 ) != 0 ) { DWORD done = FALSE; DWORD decoded = 0; DWORD size = pmb->dsize; TMem< BYTE > buf; if ( !buf.allocate( size + 1 ) ) return FALSE; // Do the decode if ( CBase64::Decode( (LPCTSTR)pmb->pdata, &size, buf, &decoded, &done ) && decoded > 0 ) { // Allocate buffer of correct size LPBYTE cbuf = new BYTE[ decoded + 1 ]; if ( cbuf == NULL ) return FALSE; // Copy data memcpy( cbuf, buf, decoded ); // Save decoded data delete [] pmb->pdata; pmb->pdata = cbuf; pmb->dsize = decoded; pmb->f1 |= MBF1_DECODED; } // end if } // end if // If quoted-printable encoded else if ( ( pmb->encode & MBEN_QP ) != 0 ) { DWORD size = pmb->dsize; TMem< char > buf; if ( !buf.allocate( size + 1 ) ) return FALSE; if ( DecodeQP( (LPCTSTR)pmb->pdata, pmb->dsize, buf, &size ) ) { // Allocate buffer of correct size LPBYTE cbuf = new BYTE[ size + 1 ]; if ( cbuf == NULL ) return FALSE; // Copy data memcpy( cbuf, buf, size ); // Save decoded data delete [] pmb->pdata; pmb->pdata = cbuf; pmb->dsize = size; pmb->f1 |= MBF1_DECODED; } // end if } // end else if return TRUE; }