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