00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
#include "kmime_parsers.h"
00017
00018
#include <qregexp.h>
00019
00020
using namespace KMime::Parser;
00021
00022
namespace KMime {
00023
namespace Parser {
00024
00025
00026 MultiPart::MultiPart(
const QCString &src,
const QCString &boundary)
00027 {
00028 s_rc=src;
00029 b_oundary=boundary;
00030 }
00031
00032
00033
bool MultiPart::parse()
00034 {
00035
QCString b=
"--"+b_oundary, part;
00036
int pos1=0, pos2=0, blen=b.length();
00037
00038 p_arts.clear();
00039
00040
00041
while(1) {
00042
if( (pos1=s_rc.find(b, pos1))==-1 || pos1==0 || s_rc[pos1-1]==
'\n' )
00043
break;
00044 pos1+=blen;
00045 }
00046
00047
if(pos1>-1) {
00048 pos1+=blen;
00049
if(s_rc[pos1]==
'-' && s_rc[pos1+1]==
'-')
00050 pos1=-1;
00051
else if( (pos1-blen)>1 )
00052 p_reamble=s_rc.left(pos1-blen);
00053 }
00054
00055
00056
while(pos1>-1 && pos2>-1) {
00057
00058
00059
if( (pos1=s_rc.find(
'\n', pos1))>-1 ) {
00060
00061 pos2=++pos1;
00062
while(1) {
00063
if( (pos2=s_rc.find(b, pos2))==-1 || s_rc[pos2-1]==
'\n' )
00064
break;
00065 pos2+=blen;
00066 }
00067
00068
if(pos2==-1) {
00069 part=s_rc.mid(pos1, s_rc.length()-pos1);
00070 p_arts.append(part);
00071 pos1=-1;
00072 pos2=-1;
00073 }
00074
else {
00075 part=s_rc.mid(pos1, pos2-pos1);
00076 p_arts.append(part);
00077 pos2+=blen;
00078
if(s_rc[pos2]==
'-' && s_rc[pos2+1]==
'-') {
00079 pos1=pos2+2;
00080
if( (pos1=s_rc.find(
'\n', pos1))>-1 )
00081 e_pilouge=s_rc.mid(++pos1, s_rc.length()-pos1);
00082 pos1=-1;
00083 pos2=-1;
00084 }
00085
else {
00086 pos1=pos2;
00087 }
00088 }
00089 }
00090 }
00091
00092
return (!p_arts.isEmpty());
00093 }
00094
00095
00096
00097
00098 NonMimeParser::NonMimeParser(
const QCString &src) :
00099 s_rc(src), p_artNr(-1), t_otalNr(-1)
00100 {}
00101
00105 QCString NonMimeParser::guessMimeType(
const QCString& fileName)
00106 {
00107
QCString tmp, mimeType;
00108
int pos;
00109
00110
if(!fileName.isEmpty()) {
00111 pos=fileName.findRev(
'.');
00112
if(pos++ != -1) {
00113 tmp=fileName.mid(pos, fileName.length()-pos).upper();
00114
if(tmp==
"JPG" || tmp==
"JPEG") mimeType=
"image/jpeg";
00115
else if(tmp==
"GIF") mimeType=
"image/gif";
00116
else if(tmp==
"PNG") mimeType=
"image/png";
00117
else if(tmp==
"TIFF" || tmp==
"TIF") mimeType=
"image/tiff";
00118
else if(tmp==
"XPM") mimeType=
"image/x-xpm";
00119
else if(tmp==
"XBM") mimeType=
"image/x-xbm";
00120
else if(tmp==
"BMP") mimeType=
"image/x-bmp";
00121
else if(tmp==
"TXT" ||
00122 tmp==
"ASC" ||
00123 tmp==
"H" ||
00124 tmp==
"C" ||
00125 tmp==
"CC" ||
00126 tmp==
"CPP") mimeType=
"text/plain";
00127
else if(tmp==
"HTML" || tmp==
"HTM") mimeType=
"text/html";
00128
else mimeType=
"application/octet-stream";
00129 }
00130
else mimeType=
"application/octet-stream";
00131 }
00132
else mimeType=
"application/octet-stream";
00133
00134
return mimeType;
00135 }
00136
00137
00138
00139
00140 UUEncoded::UUEncoded(
const QCString &src,
const QCString &subject) :
00141
NonMimeParser(src), s_ubject(subject)
00142 {}
00143
00144
00145
bool UUEncoded::parse()
00146 {
00147
int currentPos=0;
00148
bool success=
true, firstIteration=
true;
00149
00150
while (success) {
00151
int beginPos=currentPos, uuStart=currentPos, endPos=0, lineCount=0, MCount=0, pos=0, len=0;
00152
bool containsBegin=
false, containsEnd=
false;
00153
QCString tmp,fileName;
00154
00155
if( (beginPos=s_rc.find(
QRegExp(
"begin [0-9][0-9][0-9]"),currentPos))>-1 && (beginPos==0 || s_rc.at(beginPos-1)==
'\n') ) {
00156 containsBegin=
true;
00157 uuStart=s_rc.find(
'\n', beginPos);
00158
if(uuStart==-1) {
00159 success =
false;
00160
break;
00161 }
else
00162 uuStart++;
00163 }
00164
else beginPos=currentPos;
00165
00166
if ( (endPos=s_rc.find(
"\nend",(uuStart>0)? uuStart-1:0))==-1 )
00167 endPos=s_rc.length();
00168
else
00169 containsEnd=
true;
00170
00171
if ((containsBegin && containsEnd) || firstIteration) {
00172
00173
00174
00175
for(
int idx=uuStart; idx<endPos; idx++)
00176
if(s_rc[idx]==
'\n') {
00177 lineCount++;
00178
if(idx+1<endPos && s_rc[idx+1]==
'M') {
00179 idx++;
00180 MCount++;
00181 }
00182 }
00183
00184
00185
if( MCount==0 || (lineCount-MCount)>10 ||
00186 ((!containsBegin || !containsEnd) && (MCount<15)) ) {
00187 success =
false;
00188
break;
00189 }
00190
00191
if( (!containsBegin || !containsEnd) && s_ubject) {
00192
QRegExp rx(
"[0-9]+/[0-9]+");
00193 pos=rx.search(
QString(s_ubject), 0);
00194 len=rx.matchedLength();
00195
if(pos!=-1) {
00196 tmp=s_ubject.mid(pos, len);
00197 pos=tmp.find(
'/');
00198 p_artNr=tmp.left(pos).toInt();
00199 t_otalNr=tmp.right(tmp.length()-pos-1).toInt();
00200 }
else {
00201 success =
false;
00202
break;
00203 }
00204 }
00205
00206
00207
if(beginPos>0)
00208 t_ext.append(s_rc.mid(currentPos,beginPos-currentPos));
00209
00210
if(containsBegin)
00211 fileName = s_rc.mid(beginPos+10, uuStart-beginPos-11);
00212
else
00213 fileName =
"";
00214 f_ilenames.append(fileName);
00215 b_ins.append(s_rc.mid(uuStart, endPos-uuStart+1));
00216 m_imeTypes.append(
guessMimeType(fileName));
00217 firstIteration=
false;
00218
00219
int next = s_rc.find(
'\n', endPos+1);
00220
if(next==-1) {
00221 success =
false;
00222
break;
00223 }
else
00224 next++;
00225 currentPos = next;
00226
00227 }
else {
00228 success =
false;
00229 }
00230 }
00231
00232
00233 t_ext.append(s_rc.right(s_rc.length()-currentPos));
00234
00235
return ((b_ins.count()>0) || isPartial());
00236 }
00237
00238
00239
00240
00241
00242 YENCEncoded::YENCEncoded(
const QCString &src) :
00243 NonMimeParser(src)
00244 {}
00245
00246
00247
bool YENCEncoded::yencMeta(
QCString& src,
const QCString& name,
int* value)
00248 {
00249
bool found =
false;
00250
QCString sought=name +
"=";
00251
00252
int iPos=src.find( sought);
00253
if (iPos>-1) {
00254
int pos1=src.find(
' ', iPos);
00255
int pos2=src.find(
'\r', iPos);
00256
int pos3=src.find(
'\t', iPos);
00257
int pos4=src.find(
'\n', iPos);
00258
if (pos2>=0 && (pos1<0 || pos1>pos2))
00259 pos1=pos2;
00260
if (pos3>=0 && (pos1<0 || pos1>pos3))
00261 pos1=pos3;
00262
if (pos4>=0 && (pos1<0 || pos1>pos4))
00263 pos1=pos4;
00264 iPos=src.findRev(
'=', pos1)+1;
00265
if (iPos<pos1) {
00266
char c=src.at( iPos);
00267
if ( c>=
'0' && c<=
'9') {
00268 found=
true;
00269 *value=src.mid( iPos, pos1-iPos).toInt();
00270 }
00271 }
00272 }
00273
return found;
00274 }
00275
00276
00277
bool YENCEncoded::parse()
00278 {
00279
int currentPos=0;
00280
bool success=
true;
00281
00282
while (success) {
00283
int beginPos=currentPos, yencStart=currentPos;
00284
bool containsPart=
false;
00285
QCString fileName,mimeType;
00286
00287
if ((beginPos=s_rc.find(
"=ybegin ", currentPos))>-1 && ( beginPos==0 || s_rc.at( beginPos-1)==
'\n') ) {
00288 yencStart=s_rc.find(
'\n', beginPos);
00289
if (yencStart==-1) {
00290 success =
false;
00291
break;
00292 }
else {
00293 yencStart++;
00294
if (s_rc.find(
"=ypart", yencStart)==yencStart) {
00295 containsPart=
true;
00296 yencStart=s_rc.find(
'\n', yencStart);
00297
if ( yencStart== -1) {
00298 success=
false;
00299
break;
00300 }
00301 yencStart++;
00302 }
00303 }
00304
00305
00306
00307
QCString meta=s_rc.mid(beginPos, yencStart-beginPos);
00308
int namePos=meta.find(
"name=");
00309
if (namePos== -1) {
00310 success=
false;
00311
break;
00312 }
00313
int eolPos=meta.find(
'\r', namePos);
00314
if (eolPos== -1)
00315 eolPos=meta.find(
'\n', namePos);
00316
if (eolPos== -1) {
00317 success=
false;
00318
break;
00319 }
00320 fileName=meta.mid(namePos+5, eolPos-(namePos+5));
00321
00322
00323
int yencLine;
00324
if (!yencMeta(meta,
"line", ¥cLine)) {
00325 success=
false;
00326
break;
00327 }
00328
int yencSize;
00329
if (!yencMeta( meta,
"size", ¥cSize)) {
00330 success=
false;
00331
break;
00332 }
00333
00334
int partBegin, partEnd;
00335
if (containsPart) {
00336
if (!yencMeta(meta,
"part", &p_artNr)) {
00337 success=
false;
00338
break;
00339 }
00340
if (!yencMeta(meta,
"begin", &partBegin) || !
00341 yencMeta(meta,
"end", &partEnd)) {
00342 success=
false;
00343
break;
00344 }
00345
if (!yencMeta(meta,
"total", &t_otalNr))
00346 t_otalNr=p_artNr+1;
00347
if (yencSize==partEnd-partBegin+1)
00348 t_otalNr=1;
else
00349 yencSize=partEnd-partBegin+1;
00350 }
00351
00352
00353
int totalSize=0;
00354
int pos=yencStart;
00355
int len=s_rc.length();
00356
bool lineStart=
true;
00357
int lineLength=0;
00358
bool containsEnd=
false;
00359
QByteArray binary =
QByteArray(yencSize);
00360
while (pos<len) {
00361
int ch=s_rc.at(pos);
00362
if (ch<0)
00363 ch+=256;
00364
if (ch==
'\r')
00365 {
00366
if (lineLength!=yencLine && totalSize!=yencSize)
00367
break;
00368 pos++;
00369 }
00370
else if (ch==
'\n')
00371 {
00372 lineStart=
true;
00373 lineLength=0;
00374 pos++;
00375 }
00376
else
00377 {
00378
if (ch==
'=')
00379 {
00380
if (pos+1<len)
00381 {
00382 ch=s_rc.at( pos+1);
00383
if (lineStart && ch==
'y')
00384 {
00385 containsEnd=
true;
00386
break;
00387 }
00388 pos+=2;
00389 ch-=64+42;
00390
if (ch<0)
00391 ch+=256;
00392
if (totalSize>=yencSize)
00393
break;
00394 binary.at(totalSize++)=ch;
00395 lineLength++;
00396 }
00397
else
00398
break;
00399 }
00400
else
00401 {
00402 ch-=42;
00403
if (ch<0)
00404 ch+=256;
00405
if (totalSize>=yencSize)
00406
break;
00407 binary.at(totalSize++)=ch;
00408 lineLength++;
00409 pos++;
00410 }
00411 lineStart=
false;
00412 }
00413 }
00414
00415
if (!containsEnd)
00416 {
00417 success=
false;
00418
break;
00419 }
00420
if (totalSize!=yencSize)
00421 {
00422 success=
false;
00423
break;
00424 }
00425
00426
00427 eolPos=s_rc.find(
'\n', pos);
00428
if (eolPos== -1)
00429 {
00430 success=
false;
00431
break;
00432 }
00433 meta=s_rc.mid(pos, eolPos-pos);
00434
if (!yencMeta(meta,
"size", &totalSize))
00435 {
00436 success=
false;
00437
break;
00438 }
00439
if (totalSize!=yencSize)
00440 {
00441 success=
false;
00442
break;
00443 }
00444
00445 f_ilenames.append(fileName);
00446 m_imeTypes.append(
guessMimeType( fileName));
00447 b_ins.append(binary);
00448
00449
00450
if(beginPos>0)
00451 t_ext.append(s_rc.mid(currentPos,beginPos-currentPos));
00452 currentPos = eolPos+1;
00453
00454 }
else {
00455 success =
false;
00456 }
00457 }
00458
00459
00460 t_ext.append(s_rc.right(s_rc.length()-currentPos));
00461
00462
return b_ins.count()>0;
00463 }
00464
00465 }
00466 }