Interesting question!  I dug around in my parchment scrolls, and it
turns out that the ambiguous order of execution goes way back.

My ancient K & R says, "expressions involving one of the associative and
commutative operators (*, +, &, ^, |) can be rearranged even when
parenthesized.  In most cases this makes no difference whatsoever; in
situations where it might, explicit temporary variables can be used to
force a particular order of execution."  A slightly less ancient copy of
Stroustrup says, "expressions involving | may be rearranged."

It's possible that the ambiguity has been resolved in later versions of
the language, but it might be wise to code defensively in this case,
especially given that at least one compiler is apparently capable of
choosing either order of execution.  Ideally, the code would be reviewed
for similar uses of bitwise operators.

> -----Original Message-----
> From: David Landwehr [mailto:[EMAIL PROTECTED] 
> Sent: Wednesday, March 09, 2005 10:25 AM
> To: security-dev@xml.apache.org
> Subject: RE: Bug in XSCryptCryptoBase64.cpp
> 
> To the best of my knowledge this:
> int b[2] = {0xf0, 0x0f};
> int i=0;
> int t = b[i++] | b[i++];
> 
> Will evaluate to t=0xf0 and i=2.
> 
> /David
> 
> -----Original Message-----
> From: Milan Tomic [mailto:[EMAIL PROTECTED] 
> Sent: 9. marts 2005 07:26
> To: security-dev@xml.apache.org
> Subject: RE: Bug in XSCryptCryptoBase64.cpp
> 
> Hi,
> 
> I remember I have reported this long time ago and I am surprised that
> fix is not in the CVS. The problem is not in [] operator, but order of
> execution (from left to right or from right to left) is not defined in
> C++ specification for | operator and it is left to compiler to decide
> should right side be executed before left side of | operator. 
> This line
> should be broken into:
> 
> t = ((m_inputBuffer[i++] << 4) & 0x30);
> t |= (m_inputBuffer[i] >> 4);
> 
> Best regards,
> Milan
> 
> 
> > -----Original Message-----
> > From: David Landwehr [mailto:[EMAIL PROTECTED] 
> > Sent: Tuesday, March 08, 2005 10:34 PM
> > To: security-dev@xml.apache.org
> > Subject: Bug in XSCryptCryptoBase64.cpp
> > 
> > 
> > Hi,
> > 
> > The XSCryptCryptoBase64 has a bug in the base 64 encoding 
> > routine (encode). The problem is the following type of logic:
> > 
> >  t = ((m_inputBuffer[i++] << 4) & 0x30) | (m_inputBuffer[i] >> 4);
> > 
> > Normally i will only be increment after the entire 
> > expression, so it is identical to:
> >   t = ((m_inputBuffer[i] << 4) & 0x30) | (m_inputBuffer[i] >> 4);
> >   i++;
> > 
> > However because Microsoft Visual C Compiler seems to have a 
> > problem with overloaded [] operator, your code works as you 
> > original expected when you compile in Debug mode. That is it 
> > will increment i just before evaluating the r-value of the |. 
> > In Release mode however the compiler will evaluate the 
> > expression in the correct form:
> >   t = ((m_inputBuffer[i] << 4) & 0x30) | (m_inputBuffer[i] >> 4);
> > 
> > And this makes an incorrect base 64 encoding. 
> > 
> > To solve the problem you should write the code as:
> >   t = ((m_inputBuffer[i] << 4) & 0x30) | (m_inputBuffer[i+1] >> 4);
> >   i++;
> > 
> > Best regards,
> > David
> > 
> > PS for fun, this is a piece of code demonstrating the problem 
> > in MVC (try compile it in Release and Debug mode and see the 
> > difference in output): class test {
> >   int* b;
> > public:
> >   test() {
> >     b = new int[2];
> >     b[0] = 0x0f;
> >     b[1] = 0xf0;
> >   }
> > 
> > 
> >   int operator [](int i) {
> >     return b[i];
> >   }
> > };
> > 
> > int _tmain(int argc, _TCHAR* argv[])
> > {
> >   test b;
> >   int i=0;
> >   //t = ((m_inputBuffer[i++] << 2) & 0x3C) | 
> (m_inputBuffer[i] >> 6);
> >  
> >   int k = ((b[i++]<<4) & 0xff ) | (b[i] >> 4);
> > 
> >   printf("The correct value should be 0x0f=0x%x, i=%d\n", k, i);
> > 
> >   return 0;
> > }
> > 
> 
> 
> 
> 

Reply via email to