diff options
Diffstat (limited to 'protocols/YAMN/src/mails/decode.cpp')
-rw-r--r-- | protocols/YAMN/src/mails/decode.cpp | 413 |
1 files changed, 196 insertions, 217 deletions
diff --git a/protocols/YAMN/src/mails/decode.cpp b/protocols/YAMN/src/mails/decode.cpp index e0070658eb..414edfce60 100644 --- a/protocols/YAMN/src/mails/decode.cpp +++ b/protocols/YAMN/src/mails/decode.cpp @@ -158,19 +158,19 @@ int CPLENSUPP = 1; //Gets codepage ID from string representing charset such as "iso-8859-1" // input- the string // size- max length of input string -int GetCharsetFromString(char *input,size_t size); +int GetCharsetFromString(char *input, size_t size); //HexValue to DecValue ('a' to 10) // HexValue- hexa value ('a') // DecValue- poiner where to store dec value // returns 0 if not success -int FromHexa(char HexValue,char *DecValue); +int FromHexa(char HexValue, char *DecValue); //Decodes a char from Base64 // Base64Value- input char in Base64 // DecValue- pointer where to store the result // returns 0 if not success -int FromBase64(char Base64Value,char *DecValue); +int FromBase64(char Base64Value, char *DecValue); //Decodes string in quoted printable // Src- input string @@ -178,58 +178,57 @@ int FromBase64(char Base64Value,char *DecValue); // DstLen- how max long should be output string // isQ- if is "Q-encoding" modification. should be TRUE in headers // always returns 1 -int DecodeQuotedPrintable(char *Src,char *Dst,int DstLen, BOOL isQ); +int DecodeQuotedPrintable(char *Src, char *Dst, int DstLen, BOOL isQ); //Decodes string in base64 // Src- input string // Dst- where to store output string // DstLen- how max long should be output string // returns 0 if string was not properly decoded -int DecodeBase64(char *Src,char *Dst,int DstLen); +int DecodeBase64(char *Src, char *Dst, int DstLen); //Converts string to unicode from string with specified codepage // stream- input string // cp- codepage of input string // out- pointer to new allocated memory that contains unicode string -int ConvertStringToUnicode(char *stream,unsigned int cp,wchar_t **out); +int ConvertStringToUnicode(char *stream, unsigned int cp, wchar_t **out); //Converts string from MIME header to unicode // stream- input string // cp- codepage of input string // storeto- pointer to memory that contains unicode string // mode- MIME_PLAIN or MIME_MAIL (MIME_MAIL deletes '"' from start and end of string) -void ConvertCodedStringToUnicode(char *stream,wchar_t **storeto,uint32_t cp,int mode); +void ConvertCodedStringToUnicode(char *stream, wchar_t **storeto, uint32_t cp, int mode); //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- -int GetCharsetFromString(char *input,size_t size) +int GetCharsetFromString(char *input, size_t size) //"ISO-8859-1" to ID from table { - char *pin=input; - char *pout,*parser; + char *pin = input; + char *pout, *parser; - if ((size<1) || (parser=pout=new char[size+1])==nullptr) + if ((size < 1) || (parser = pout = new char[size + 1]) == nullptr) return -1; - while((*pin != 0) && (pin-input< (INT_PTR)size)) - { - if ((*pin>='a') && (*pin<='z')) - *parser++=*(pin++)-('a'-'A'); // make it capital + while ((*pin != 0) && (pin - input < (INT_PTR)size)) { + if ((*pin >= 'a') && (*pin <= 'z')) + *parser++ = *(pin++) - ('a' - 'A'); // make it capital //else if (*pin=='\"') // this is already done in ExtractFromContentType // *pin++; //skip the quotes if any - else - *parser++=*pin++; + else + *parser++ = *pin++; } *parser = 0; -#ifdef DEBUG_DECODECODEPAGE - DebugLog(DecodeFile,"<CodePage>%s</CodePage>",pout); -#endif - for (int i=0;i<CPLENALL;i++) { + #ifdef DEBUG_DECODECODEPAGE + DebugLog(DecodeFile, "<CodePage>%s</CodePage>", pout); + #endif + for (int i = 0; i < CPLENALL; i++) { size_t len = mir_strlen(CodePageNamesAll[i].NameBase); - if (0==strncmp(pout,CodePageNamesAll[i].NameBase,len)) { - if (0==mir_strcmp(pout+len,CodePageNamesAll[i].NameSub)) { + if (0 == strncmp(pout, CodePageNamesAll[i].NameBase, len)) { + if (0 == mir_strcmp(pout + len, CodePageNamesAll[i].NameSub)) { delete[] pout; return CodePageNamesAll[i].CP; } @@ -239,312 +238,292 @@ int GetCharsetFromString(char *input,size_t size) return -1; //not found } -int FromHexa(char HexValue,char *DecValue) +int FromHexa(char HexValue, char *DecValue) { - if (HexValue>='0' && HexValue<='9') - { - *DecValue=HexValue-'0'; + if (HexValue >= '0' && HexValue <= '9') { + *DecValue = HexValue - '0'; return 1; } - if (HexValue>='A' && HexValue<='F') - { - *DecValue=HexValue-'A'+10; + if (HexValue >= 'A' && HexValue <= 'F') { + *DecValue = HexValue - 'A' + 10; return 1; } - if (HexValue>='a' && HexValue<='f') - { - *DecValue=HexValue-'a'+10; + if (HexValue >= 'a' && HexValue <= 'f') { + *DecValue = HexValue - 'a' + 10; return 1; } return 0; } -int FromBase64(char Base64Value,char *DecValue) +int FromBase64(char Base64Value, char *DecValue) { - if (Base64Value>='A' && Base64Value<='Z') - { - *DecValue=Base64Value-'A'; + if (Base64Value >= 'A' && Base64Value <= 'Z') { + *DecValue = Base64Value - 'A'; return 1; } - if (Base64Value>='a' && Base64Value<='z') - { - *DecValue=Base64Value-'a'+26; + if (Base64Value >= 'a' && Base64Value <= 'z') { + *DecValue = Base64Value - 'a' + 26; return 1; } - if (Base64Value>='0' && Base64Value<='9') - { - *DecValue=Base64Value-'0'+52; + if (Base64Value >= '0' && Base64Value <= '9') { + *DecValue = Base64Value - '0' + 52; return 1; } - if (Base64Value=='+') - { - *DecValue=Base64Value-'+'+62; + if (Base64Value == '+') { + *DecValue = Base64Value - '+' + 62; return 1; } - if (Base64Value=='/') - { - *DecValue=Base64Value-'/'+63; + if (Base64Value == '/') { + *DecValue = Base64Value - '/' + 63; return 1; } - if (Base64Value=='=') - { - *DecValue=0; + if (Base64Value == '=') { + *DecValue = 0; return 1; } return 0; } -int DecodeQuotedPrintable(char *Src,char *Dst,int DstLen, BOOL isQ) +int DecodeQuotedPrintable(char *Src, char *Dst, int DstLen, BOOL isQ) { -#ifdef DEBUG_DECODEQUOTED - char *DstTemp=Dst; - DebugLog(DecodeFile,"<Decode Quoted><Input>%s</Input>",Src); -#endif - for (int Counter=0;(*Src != 0) && DstLen && (Counter++<DstLen);Src++,Dst++) - if (*Src=='=') - { + #ifdef DEBUG_DECODEQUOTED + char *DstTemp = Dst; + DebugLog(DecodeFile, "<Decode Quoted><Input>%s</Input>", Src); + #endif + for (int Counter = 0; (*Src != 0) && DstLen && (Counter++ < DstLen); Src++, Dst++) + if (*Src == '=') { if (!isQ) { - if (Src[1]==0x0D) { + if (Src[1] == 0x0D) { Src++; Src++; - if (Src[0]==0x0A) Src++; + if (Src[0] == 0x0A) Src++; goto CopyCharQuotedPrintable; } - if (Src[1]==0x0A) { + if (Src[1] == 0x0A) { Src++; Src++; goto CopyCharQuotedPrintable; } } - char First,Second; - if (!FromHexa(*(++Src),&First)) - { - *Dst++='=';Src--; + char First, Second; + if (!FromHexa(*(++Src), &First)) { + *Dst++ = '='; Src--; continue; } - if (!FromHexa(*(++Src),&Second)) - { - *Dst++='=';Src--;Src--; + if (!FromHexa(*(++Src), &Second)) { + *Dst++ = '='; Src--; Src--; continue; } - *Dst=(char)(First)<<4; - *Dst+=Second; + *Dst = (char)(First) << 4; + *Dst += Second; } - else if (isQ && *Src=='_') - *Dst=' '; + else if (isQ && *Src == '_') + *Dst = ' '; else -CopyCharQuotedPrintable: // Yeah. Bad programming stile. - *Dst=*Src; - *Dst=0; -#ifdef DEBUG_DECODEQUOTED - DebugLog(DecodeFile,"<Output>%s</Output></Decode Quoted>",DstTemp); -#endif + CopyCharQuotedPrintable: // Yeah. Bad programming stile. + *Dst = *Src; + *Dst = 0; + #ifdef DEBUG_DECODEQUOTED + DebugLog(DecodeFile, "<Output>%s</Output></Decode Quoted>", DstTemp); + #endif return 1; } -int DecodeBase64(char *Src,char *Dst,int DstLen) +int DecodeBase64(char *Src, char *Dst, int DstLen) { - int Result=0; - char Locator=0,MiniResult[4]; - char *End=Dst+DstLen; - - MiniResult[0]=MiniResult[1]=MiniResult[2]=MiniResult[3]=0; - -#ifdef DEBUG_DECODEBASE64 - char *DstTemp=Dst; - DebugLog(DecodeFile,"<Decode Base64><Input>\n%s\n</Input>\n",Src); -#endif - while(*Src != 0 && DstLen && Dst != End) - { - if ((*Src==0x0D)||(*Src==0x0A)) { - Src++; + int Result = 0; + char Locator = 0, MiniResult[4]; + char *End = Dst + DstLen; + + MiniResult[0] = MiniResult[1] = MiniResult[2] = MiniResult[3] = 0; + + #ifdef DEBUG_DECODEBASE64 + char *DstTemp = Dst; + DebugLog(DecodeFile, "<Decode Base64><Input>\n%s\n</Input>\n", Src); + #endif + while (*Src != 0 && DstLen && Dst != End) { + if ((*Src == 0x0D) || (*Src == 0x0A)) { + Src++; continue; } - if ((!(Result=FromBase64(*Src,MiniResult+Locator)) && (*Src==0)) || Locator++==3) //end_of_str || end_of_4_bytes + if ((!(Result = FromBase64(*Src, MiniResult + Locator)) && (*Src == 0)) || Locator++ == 3) //end_of_str || end_of_4_bytes { - Locator=0; //next write to the first byte - *Dst++=(char)((MiniResult[0]<<2) | (MiniResult[1]>>4)); - if (Dst==End) goto end; //DstLen exceeded? - *Dst++=(char)((MiniResult[1]<<4) | (MiniResult[2]>>2)); - if (Dst==End) goto end; //someones don't like goto, but not me - *Dst++=(char)((MiniResult[2]<<6) | MiniResult[3]); - if (!Result && (*Src==0)) goto end; //end of string? - MiniResult[0]=MiniResult[1]=MiniResult[2]=MiniResult[3]=0; //zero 4byte buffer for next loop + Locator = 0; //next write to the first byte + *Dst++ = (char)((MiniResult[0] << 2) | (MiniResult[1] >> 4)); + if (Dst == End) goto end; //DstLen exceeded? + *Dst++ = (char)((MiniResult[1] << 4) | (MiniResult[2] >> 2)); + if (Dst == End) goto end; //someones don't like goto, but not me + *Dst++ = (char)((MiniResult[2] << 6) | MiniResult[3]); + if (!Result && (*Src == 0)) goto end; //end of string? + MiniResult[0] = MiniResult[1] = MiniResult[2] = MiniResult[3] = 0; //zero 4byte buffer for next loop } if (!Result) return 0; //unrecognised character occured Src++; } end: - *Dst=0; -#ifdef DEBUG_DECODEBASE64 - DebugLog(DecodeFile,"<Output>\n%s\n</Output></Decode Base64>",DstTemp); -#endif + *Dst = 0; + #ifdef DEBUG_DECODEBASE64 + DebugLog(DecodeFile, "<Output>\n%s\n</Output></Decode Base64>", DstTemp); + #endif return 1; } -int ConvertStringToUnicode(char *stream,unsigned int cp,wchar_t **out) +int ConvertStringToUnicode(char *stream, unsigned int cp, wchar_t **out) { CPINFO CPInfo; - wchar_t *temp,*src=*out,*dest; + wchar_t *temp, *src = *out, *dest; size_t outlen; - int streamlen,Index; + int streamlen, Index; //codepages, which require to have set 0 in dwFlags parameter when calling MultiByteToWideChar - uint32_t CodePagesZeroFlags[]={50220,50221,50222,50225,50227,50229,52936,54936,57002,57003,57004,57005,57006,57007,57008,57009,57010,57011,65000,65001}; - - if ((cp != CP_ACP) && (cp != CP_OEMCP) && (cp != CP_MACCP) && (cp != CP_THREAD_ACP) && (cp != CP_SYMBOL) && (cp != CP_UTF7) && (cp != CP_UTF8) && !GetCPInfo(cp,&CPInfo)) - cp=CP_ACP; -#ifdef DEBUG_DECODECODEPAGE - DebugLog(DecodeFile,"<CodePage #>%d</CodePage #>",cp); -#endif - - for (Index=0;Index<sizeof(CodePagesZeroFlags)/sizeof(CodePagesZeroFlags[0]);Index++) - if (CodePagesZeroFlags[Index]==cp) - { - Index=-1; + uint32_t CodePagesZeroFlags[] = {50220, 50221, 50222, 50225, 50227, 50229, 52936, 54936, 57002, 57003, 57004, 57005, 57006, 57007, 57008, 57009, 57010, 57011, 65000, 65001}; + + if ((cp != CP_ACP) && (cp != CP_OEMCP) && (cp != CP_MACCP) && (cp != CP_THREAD_ACP) && (cp != CP_SYMBOL) && (cp != CP_UTF7) && (cp != CP_UTF8) && !GetCPInfo(cp, &CPInfo)) + cp = CP_ACP; + #ifdef DEBUG_DECODECODEPAGE + DebugLog(DecodeFile, "<CodePage #>%d</CodePage #>", cp); + #endif + + for (Index = 0; Index < sizeof(CodePagesZeroFlags) / sizeof(CodePagesZeroFlags[0]); Index++) + if (CodePagesZeroFlags[Index] == cp) { + Index = -1; break; } - if (Index==-1) - streamlen=MultiByteToWideChar(cp,0,stream,-1,nullptr,0); + if (Index == -1) + streamlen = MultiByteToWideChar(cp, 0, stream, -1, nullptr, 0); else - streamlen=MultiByteToWideChar(cp,MB_USEGLYPHCHARS,stream,-1,nullptr,0); + streamlen = MultiByteToWideChar(cp, MB_USEGLYPHCHARS, stream, -1, nullptr, 0); if (*out != nullptr) - outlen=mir_wstrlen(*out); + outlen = mir_wstrlen(*out); else - outlen=0; - temp=new wchar_t[streamlen+outlen+1]; - - if (*out != nullptr) - { - for (dest=temp;*src != (wchar_t)0;src++,dest++) //copy old string from *out to temp - *dest=*src; -// *dest++=L' '; //add space? - delete[] *out; + outlen = 0; + temp = new wchar_t[streamlen + outlen + 1]; + + if (*out != nullptr) { + for (dest = temp; *src != (wchar_t)0; src++, dest++) //copy old string from *out to temp + *dest = *src; + // *dest++=L' '; //add space? + delete[] * out; } else - dest=temp; - *out=temp; - - if (Index==-1) - { - if (!MultiByteToWideChar(cp,0,stream,-1,dest,streamlen)) + dest = temp; + *out = temp; + + if (Index == -1) { + if (!MultiByteToWideChar(cp, 0, stream, -1, dest, streamlen)) return 0; } - else - { - if (!MultiByteToWideChar(cp,MB_USEGLYPHCHARS,stream,-1,dest,streamlen)) + else { + if (!MultiByteToWideChar(cp, MB_USEGLYPHCHARS, stream, -1, dest, streamlen)) return 0; } return 1; } -void ConvertCodedStringToUnicode(char *stream,wchar_t **storeto,uint32_t cp,int mode) +void ConvertCodedStringToUnicode(char *stream, wchar_t **storeto, uint32_t cp, int mode) { - char *start=stream,*finder,*finderend; - char Encoding=0; + char *start = stream, *finder, *finderend; + char Encoding = 0; - if (stream==nullptr) + if (stream == nullptr) return; - while(WS(start)) start++; - wchar_t *tempstore=nullptr; - if (!ConvertStringToUnicode(stream,cp,&tempstore))return; + while (WS(start)) start++; + wchar_t *tempstore = nullptr; + if (!ConvertStringToUnicode(stream, cp, &tempstore))return; size_t tempstoreLength = mir_wstrlen(tempstore); - + size_t outind = 0; - while(*start != 0) { + while (*start != 0) { if (CODES(start)) { - finder=start+2;finderend=finder; - while(!CODED(finderend) && !EOS(finderend)) finderend++; + finder = start + 2; finderend = finder; + while (!CODED(finderend) && !EOS(finderend)) finderend++; start = finderend; - if (CODED(finderend)) - { - Encoding=*(finderend+1); - switch(Encoding) - { - case 'b': - case 'B': - case 'q': - case 'Q': - break; - default: - goto NotEncoded; + if (CODED(finderend)) { + Encoding = *(finderend + 1); + switch (Encoding) { + case 'b': + case 'B': + case 'q': + case 'Q': + break; + default: + goto NotEncoded; } - if (-1==(cp=(uint32_t)GetCharsetFromString(finder,finderend-finder))) - cp=CP_ACP; - if (Encoding != 0) - { - int size = 0,codeend; + if (-1 == (cp = (uint32_t)GetCharsetFromString(finder, finderend - finder))) + cp = CP_ACP; + if (Encoding != 0) { + int size = 0, codeend; char *pcodeend = nullptr; - finder=finderend+2; + finder = finderend + 2; if (CODED(finder)) finder++; - while(WS(finder)) finder++; - finderend=finder; - while(!CODEE(finderend) && !EOS(finderend)) finderend++; - if (codeend=CODEE(finderend)) - pcodeend=finderend; - while(WS(finderend-1)) finderend--; - if ((mode==MIME_MAIL) && (((*finder=='"') && (*(finderend-1)=='"')))) - { + while (WS(finder)) finder++; + finderend = finder; + while (!CODEE(finderend) && !EOS(finderend)) finderend++; + if (codeend = CODEE(finderend)) + pcodeend = finderend; + while (WS(finderend - 1)) finderend--; + if ((mode == MIME_MAIL) && (((*finder == '"') && (*(finderend - 1) == '"')))) { finder++; finderend--; } - char *oneWordEncoded = new char[finderend-finder+1]; - strncpy(oneWordEncoded,finder,finderend-finder); - oneWordEncoded[finderend-finder]=0; - switch(Encoding) - { - case 'b': - case 'B': - size=(finderend-finder)*3/4+3+1+1; - break; - case 'q': - case 'Q': - size=finderend-finder+1+1; - break; + char *oneWordEncoded = new char[finderend - finder + 1]; + strncpy(oneWordEncoded, finder, finderend - finder); + oneWordEncoded[finderend - finder] = 0; + switch (Encoding) { + case 'b': + case 'B': + size = (finderend - finder) * 3 / 4 + 3 + 1 + 1; + break; + case 'q': + case 'Q': + size = finderend - finder + 1 + 1; + break; } - char *DecodedResult = new char[size+1]; - switch(Encoding) - { - case 'q': - case 'Q': - DecodeQuotedPrintable(oneWordEncoded,DecodedResult,size, TRUE); - break; - case 'b': - case 'B': - DecodeBase64(oneWordEncoded,DecodedResult,size); - break; + char *DecodedResult = new char[size + 1]; + switch (Encoding) { + case 'q': + case 'Q': + DecodeQuotedPrintable(oneWordEncoded, DecodedResult, size, TRUE); + break; + case 'b': + case 'B': + DecodeBase64(oneWordEncoded, DecodedResult, size); + break; } delete[] oneWordEncoded; if (codeend) - finderend=pcodeend+2; + finderend = pcodeend + 2; if (WS(finderend)) //if string continues and there's some whitespace, add space to string that is to be converted { - size_t len=mir_strlen(DecodedResult); - DecodedResult[len]=' '; - DecodedResult[len+1]=0; + size_t len = mir_strlen(DecodedResult); + DecodedResult[len] = ' '; + DecodedResult[len + 1] = 0; finderend++; } - wchar_t *oneWord=nullptr; - if (ConvertStringToUnicode(DecodedResult,cp,&oneWord)) { + wchar_t *oneWord = nullptr; + if (ConvertStringToUnicode(DecodedResult, cp, &oneWord)) { size_t len = mir_wstrlen(oneWord); - memcpy(&tempstore[outind],oneWord,len*sizeof(wchar_t)); + memcpy(&tempstore[outind], oneWord, len * sizeof(wchar_t)); outind += len; } delete oneWord; oneWord = nullptr; delete[] DecodedResult; start = finderend; - } else if (!EOS(start)) start++; - } else if (!EOS(start)) start++; - }else{ + } + else if (!EOS(start)) start++; + } + else if (!EOS(start)) start++; + } + else { NotEncoded: - tempstore[outind] = tempstore[start-stream]; + tempstore[outind] = tempstore[start - stream]; outind++; if (outind > tempstoreLength) break; start++; |