http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2639

*** shadow/2639 Thu Jul 19 08:45:31 2001
--- shadow/2639.tmp.4122        Thu Jul 19 09:53:58 2001
***************
*** 93,96 ****
  Good news!  I'm able to reproduce this problem.  I added a "-out outfile.out" to 
  the command line and the error occurred.  I'm looking into it further now.  
  Thanks for your persistence with this.
! Gary
--- 93,151 ----
  Good news!  I'm able to reproduce this problem.  I added a "-out outfile.out" to 
  the command line and the error occurred.  I'm looking into it further now.  
  Thanks for your persistence with this.
! Gary
! 
! ------- Additional Comments From [EMAIL PROTECTED]  2001-07-19 09:53 -------
! Okay.  I've found the problem here but I wanted to check with Scott before 
! implementing a solution because this is in a somewhat performance-critical piece 
! of code.  The problem occurs in all three write(..) -- not writeDirect(..) -- 
! methods of org.apache.xalan.serialize.WriteToUTF8Buffered.
! 
! Before populating the buffer (named buf), the write() methods check to make sure 
! that there is still room in the buffer.  They do this by checking the length of 
! the remaining room in the buffer versus the length of the incoming character 
! array or character or String.  However, a single character could turn in to up 
! to 3 characters after the UTF-8 algorithm applies and this is not taken into 
! account.
! 
! Here is the scenario that is happening here.  There is room for 6 more 
! characters in the output buffer.  The input string is: 
! "\u00a0:\u00a0\u00a0\u00a0" which is five characters long so no buffer flush is 
! performed.  However, each of the \u00a0 expands to two bytes with UTF8.  So, we 
! overflow the buffer and get the IndexOutOfBoundsException.
! 
! I can think of a couple of ways to fix this:  (1) When checking capacity, 
! multiply the incoming length by 3.  This represents the maximum expanded length 
! of a character so we are assured that it will fit in the buffer.  However, this 
! requires a multiply which I don't especially like. (2) When we do discover that 
! multiple bytes are required, we could account for it then so the code would look 
! like this:
! 
!       if (c < 0x80)
!         buf[count++] = (byte) (c);
!       else if (c < 0x800)
!       {
!         if (count > buf.length - 2)
!           flushBuffer();
!         buf[count++] = (byte) (0xc0 + (c >> 6));
!         buf[count++] = (byte) (0x80 + (c & 0x3f));
!       }
!       else
!       {
!         if (count > buf.length - 3)
!           flushBuffer();
!         buf[count++] = (byte) (0xe0 + (c >> 12));
!         buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
!         buf[count++] = (byte) (0x80 + (c & 0x3f));
!       }
! 
! This has the advantage of avoiding the multiply but results in extra if 
! statements but only in those cases where we have non-7 bit ASCII characters.  
! I'm leaning toward the second alternative since I think that non-ASCII 
! characters occur relatively infrequently (at least for me) and I hate to pay the 
! penalty for a multiply on every write.  But, I'm willing to be convinced 
! otherwise or to be shown another alternative.  BTW, I don't favor catching the 
! IndexOutOfBoundsException as a reasonable alternative.
! 
! Thoughts?
! Gary

Reply via email to