source:
npl/overig/libvmime/vmime-wrongly-padded-B64-words.diff
@
c5c522c
Last change on this file since c5c522c was c5c522c, checked in by , 8 years ago | |
---|---|
|
|
File size: 6.1 KB |
-
src/word.cpp
diff -urb libvmime-0.9.2-patched/src/word.cpp libvmime-0.9.2/src/word.cpp
old new 64 64 65 65 66 66 ref <word> word::parseNext(const string& buffer, const string::size_type position, 67 const string::size_type end, string::size_type* newPosition, 68 bool prevIsEncoded, bool* isEncoded, bool isFirst) 67 const string::size_type end, string::size_type* newPosition, parserState* state) 69 68 { 70 69 string::size_type pos = position; 71 70 … … 120 119 121 120 if (!unencoded.empty()) 122 121 { 123 if ( prevIsEncoded)122 if (state->prevIsEncoded && !state->isFirst) 124 123 unencoded = whiteSpaces + unencoded; 125 124 126 125 ref <word> w = vmime::create <word>(unencoded, charset(charsets::US_ASCII)); … … 129 128 if (newPosition) 130 129 *newPosition = pos; 131 130 132 if (isEncoded)133 *isEncoded= false;131 state->prevIsEncoded = false; 132 state->isFirst = false; 134 133 135 134 return (w); 136 135 } … … 181 180 pos += 2; // ?= 182 181 183 182 ref <word> w = vmime::create <word>(); 184 w->parse (buffer, wordStart, pos, NULL);183 w->parseWithState(buffer, wordStart, pos, NULL, state); 185 184 186 185 if (newPosition) 187 186 *newPosition = pos; 188 187 189 if (isEncoded)190 *isEncoded = true;188 state->prevIsEncoded = true; 189 state->isFirst = false; 191 190 192 191 return (w); 193 192 } … … 195 194 ++pos; 196 195 } 197 196 198 if (startPos != end && ! isFirst &&prevIsEncoded)197 if (startPos != end && !state->isFirst && state->prevIsEncoded) 199 198 unencoded += whiteSpaces; 200 199 201 200 if (startPos != end) … … 210 209 if (newPosition) 211 210 *newPosition = end; 212 211 213 if (isEncoded)214 *isEncoded= false;212 state->prevIsEncoded = false; 213 state->isFirst = false; 215 214 216 215 return (w); 217 216 } … … 228 227 229 228 string::size_type pos = position; 230 229 231 bool prevIsEncoded = false;230 parserState state; 232 231 233 while ((w = word::parseNext(buffer, pos, end, &pos, prevIsEncoded, &prevIsEncoded, (w == NULL))) != NULL)232 while ((w = word::parseNext(buffer, pos, end, &pos, &state)) != NULL) 234 233 res.push_back(w); 235 234 236 235 if (newPosition) … … 243 242 void word::parse(const string& buffer, const string::size_type position, 244 243 const string::size_type end, string::size_type* newPosition) 245 244 { 245 parseWithState(buffer, position, end, newPosition, NULL); 246 } 247 248 249 void word::parseWithState 250 (const string& buffer, const size_t position, 251 const size_t end, size_t* newPosition, parserState* state) 252 { 246 253 if (position + 6 < end && // 6 = "=?(.+)?(.*)?=" 247 254 buffer[position] == '=' && buffer[position + 1] == '?') 248 255 { … … 289 296 if (theEncoder) 290 297 { 291 298 // Decode text 299 string encodedBuffer(dataPos, dataEnd); 292 300 string decodedBuffer; 293 301 294 utility::inputStreamStringAdapter ein(string(dataPos, dataEnd)); 302 303 if (state && !state->undecodedBytes.empty()) 304 { 305 encodedBuffer = state->undecodedBytes + encodedBuffer; 306 state->undecodedBytes.clear(); 307 } 308 309 utility::inputStreamStringAdapter ein(encodedBuffer); 295 310 utility::outputStreamStringAdapter eout(decodedBuffer); 296 311 297 theEncoder->decode(ein, eout);312 const size_t decodedLen = theEncoder->decode(ein, eout); 298 313 delete (theEncoder); 299 314 300 315 m_buffer = decodedBuffer; … … 305 320 if (newPosition) 306 321 *newPosition = (p - buffer.begin()); 307 322 323 // For Base64 encoding, ensure all bytes have been decoded. 324 // If there are remaining bytes, keep them for the next run. 325 // 326 // This allows decoding some insanities like: 327 // =?utf-8?B?5Lit5?= =?utf-8?B?paH?= 328 if (*encPos == 'B' || *encPos == 'b') 329 { 330 const size_t actualEncodedLen = encodedBuffer.length(); 331 const size_t theoricalEncodedLen = 332 ((decodedLen + ((decodedLen % 3) ? (3 - (decodedLen % 3)) : 0) ) / 3) * 4; 333 334 if (state && actualEncodedLen != theoricalEncodedLen) 335 state->undecodedBytes.assign(dataPos + theoricalEncodedLen, dataEnd); 336 } 337 308 338 return; 309 339 } 310 340 } -
vmime/word.hpp
diff -urb libvmime-0.9.2-patched/vmime/word.hpp libvmime-0.9.2/vmime/word.hpp
old new 125 125 bool prevWordIsEncoded; 126 126 bool lastCharIsSpace; 127 127 }; 128 129 class parserState 130 { 131 public: 132 133 parserState() 134 : prevIsEncoded(false), isFirst(true) 135 { 136 } 137 138 bool prevIsEncoded; 139 bool isFirst; 140 std::string undecodedBytes; 141 }; 128 142 #endif 129 143 130 144 … … 134 148 void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); 135 149 void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; 136 150 151 void parseWithState 152 (const string& buffer, 153 const size_t position, 154 const size_t end, 155 size_t* newPosition, 156 parserState* state); 157 137 158 void generate(utility::outputStream& os, const string::size_type maxLineLength, const string::size_type curLinePos, string::size_type* newLinePos, const int flags, generatorState* state) const; 138 159 139 160 const std::vector <ref <const component> > getChildComponents() const; 140 161 141 162 private: 142 163 143 static ref <word> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition, bool prevIsEncoded, bool* isEncoded, bool isFirst);164 static ref <word> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition, parserState* state); 144 165 145 166 static const std::vector <ref <word> > parseMultiple(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition); 146 167
Note: See TracBrowser
for help on using the repository browser.