[serialization] Base64 padding in basic_text_oprimitive

Hello, Code that pads base64 output with '=' looks in basic_text_oprimitive.ipp like following: std::size_t padding = 2 - count % 3; if(padding > 1) *oi = '='; if(padding > 2) *oi = '='; It will give the following transformations of a few simple strings: "012" -> "MDEy=" "0123" -> "MDEyMw" "01234" -> "MDEyMzQ" "012345" -> "MDEyMzQ1=" Which violates the principle of the base 64 that the encoded output length is multiple of 4 bytes. Right output for the samples above should be: "012" -> "MDEy" "0123" -> "MDEyMw==" "01234" -> "MDEyMzQ=" "012345" -> "MDEyMzQ1" The problem with the code above is that the condition (padding > 2) is never satisfied. I think that the proper code should look like std::size_t padding = 2 - count % 3; if (padding < 2) { *oi = '='; if (padding > 0) *oi = '='; } -- -- Vyacheslav Andrejev -- System Architect, Optech International, Inc.

Hmmm - I wasn't aware that base64 had a "principle" that output length is a multiple of 4 bytes. You could be on ot something here, I'll take another look at it. Vyacheslav E. Andrejev wrote:
Hello,
Code that pads base64 output with '=' looks in basic_text_oprimitive.ipp like following:
std::size_t padding = 2 - count % 3; if(padding > 1) *oi = '='; if(padding > 2) *oi = '=';
It will give the following transformations of a few simple strings:
"012" -> "MDEy=" "0123" -> "MDEyMw" "01234" -> "MDEyMzQ" "012345" -> "MDEyMzQ1="
Which violates the principle of the base 64 that the encoded output length is multiple of 4 bytes. Right output for the samples above should be:
"012" -> "MDEy" "0123" -> "MDEyMw==" "01234" -> "MDEyMzQ=" "012345" -> "MDEyMzQ1"
The problem with the code above is that the condition (padding > 2) is never satisfied. I think that the proper code should look like
std::size_t padding = 2 - count % 3; if (padding < 2) { *oi = '='; if (padding > 0) *oi = '='; }

Hello Robert, RR> Hmmm - I wasn't aware that base64 had a "principle" that output RR> length is a multiple of 4 bytes. Well, I doubt that it is fundamental, more likely the fundamental is to notify decoder that the rest of a stream should be padded with zeros when it encounters '=' sign at the end. But the consequence of it is definetly that base64 encoded length is multiple of 4. But anyway the point is that the code has a flaw at least since (padding > 2) is always false. Slava. -- -- Vyacheslav Andrejev -- System Architect, Optech International, Inc.

The problem with ths fix is that the current system reads the number of bytes and advances the iterator only that number of bytes. So if I were to make this change, I would also have to make another change on the base64 input. But then I would have a problem with reading old archives which woudn't have the extra byte. Nevertheless, I would much like to see a correct, portable and more widely usable version of this iterator. So, If you would like to see this do the following: a) open up a track ticket on this. b) post patch for output AND input c) run tests - at least test_bas64 iterator Then I'll look at rolling it in - along with tweaks to make it backward compatible for existing archives. Let no good deed go unpunished. Robert Ramey Vyacheslav E. Andrejev wrote:
Hello,
Code that pads base64 output with '=' looks in basic_text_oprimitive.ipp like following:
std::size_t padding = 2 - count % 3; if(padding > 1) *oi = '='; if(padding > 2) *oi = '=';
It will give the following transformations of a few simple strings:
"012" -> "MDEy=" "0123" -> "MDEyMw" "01234" -> "MDEyMzQ" "012345" -> "MDEyMzQ1="
Which violates the principle of the base 64 that the encoded output length is multiple of 4 bytes. Right output for the samples above should be:
"012" -> "MDEy" "0123" -> "MDEyMw==" "01234" -> "MDEyMzQ=" "012345" -> "MDEyMzQ1"
The problem with the code above is that the condition (padding > 2) is never satisfied. I think that the proper code should look like
std::size_t padding = 2 - count % 3; if (padding < 2) { *oi = '='; if (padding > 0) *oi = '='; }
participants (2)
-
Robert Ramey
-
Vyacheslav E. Andrejev