Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
understanding bytes.Buffer.WriteTo panic
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  7 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Justin Israel  
View profile  
 More options Apr 29 2012, 3:10 pm
From: Justin Israel <justinisr...@gmail.com>
Date: Sun, 29 Apr 2012 12:10:32 -0700 (PDT)
Local: Sun, Apr 29 2012 3:10 pm
Subject: understanding bytes.Buffer.WriteTo panic
Since the Go1 release, I have made some unicode updates to go-
socket.io to keep it current. As a result, a new panic has appeared in
every transport beside websocket connections. I was wondering if
someone could help me understand the circumstance behind the panic so
I can try to make some head way fixing this...

As a result of the goroutine loop that is flushing the outgoing buffer
to the underlying socket connection:

c.mutex.Lock()
_, err = buf.WriteTo(c.socket)
c.mutex.Unlock()

...it's panicing with:  panic: bytes.Buffer.WriteTo: invalid Write
count

In looking at the source of Buffer.WriteTo, I am trying to understand:

182     func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
183             b.lastRead = opInvalid
184             if b.off < len(b.buf) {
185                     nBytes := b.Len()
186                     m, e := w.Write(b.buf[b.off:])
187                     if m > nBytes {
188                             panic("bytes.Buffer.WriteTo: invalid Write count")
189                     }

... what is the circumstance where more bytes can be written to the
socket than are available in the length of the source buffer?
Could this be related to my previous unicode updates and how its
comparing lengths? Or is this really some issue where its writing
unexpected amounts?

Appreciate any help that gets me pointed the right way.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kyle Lemons  
View profile  
 More options Apr 29 2012, 6:36 pm
From: Kyle Lemons <kev...@google.com>
Date: Sun, 29 Apr 2012 15:36:44 -0700
Local: Sun, Apr 29 2012 6:36 pm
Subject: Re: [go-nuts] understanding bytes.Buffer.WriteTo panic

If you're doing any transformations (especially ones that might increase
the number of bytes) on the output before you write it, you could cause
more bytes to be written.  So, in the code provided, it depends on what
Write() does.  In my transforming writers, usually I return the length of
the input or zero instead of the number returned by the underlying write.
 Probably could confuse a writer that's trying to be smart, so maybe not
the best solution, but it works :).  I ran up against this first when I
confused fmt.* by doing my own tab replacement on the back-end.

On Sun, Apr 29, 2012 at 12:10 PM, Justin Israel <justinisr...@gmail.com>wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Justin Israel  
View profile  
 More options Apr 29 2012, 11:42 pm
From: Justin Israel <justinisr...@gmail.com>
Date: Sun, 29 Apr 2012 20:42:37 -0700 (PDT)
Local: Sun, Apr 29 2012 11:42 pm
Subject: Re: understanding bytes.Buffer.WriteTo panic
Kyle, you are a genius. Thank you!
I took your advise and just returned the length of the input slice (if
not error) and it worked!
The strange thing is how this all just started happening with the
conforming to Go1. The Write methods haven't changed in this library.
There are about 5 different "transports" in this lib with Write
methods, so they all do different ops, but for instance the XHR-
POLLING transport Write looks like this:

func (s *xhrPollingSocket) Write(p []byte) (int, error) {
        if !s.connected {
                return 0, ErrNotConnected
        }
        defer s.Close()

        buf := new(bytes.Buffer)

        buf.WriteString("HTTP/1.0 200 OK\r\n")
        buf.WriteString("Content-Type: text/plain; charset=UTF-8\r\n")
        fmt.Fprintf(buf, "Content-Length: %d\r\n", len(p))

        if origin := s.req.Header.Get("Origin"); origin != "" {
                fmt.Fprintf(buf, "Access-Control-Allow-Origin: %s\r\n", origin)
                buf.WriteString("Access-Control-Allow-Credentials: true\r\n")
        }

        buf.WriteString("\r\n")
        buf.Write(p)

//      nr, err := buf.WriteTo(s.rwc)
        _, err := buf.WriteTo(s.rwc)

//      return int(nr), err
        return len(p), err

}

Those comments are where I applied the suggested fix that now works.
It does indeed modify the buffer before its written, causing the
length to mismatch for the Buffer.WriteTo
But strangely this never crashed it in the past.

On Apr 29, 3:36 pm, Kyle Lemons <kev...@google.com> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Rémy Oudompheng  
View profile  
 More options Apr 30 2012, 2:46 am
From: Rémy Oudompheng <remyoudomph...@gmail.com>
Date: Mon, 30 Apr 2012 08:46:26 +0200
Local: Mon, Apr 30 2012 2:46 am
Subject: Re: [go-nuts] Re: understanding bytes.Buffer.WriteTo panic
2012/4/30 Justin Israel <justinisr...@gmail.com>:

> Kyle, you are a genius. Thank you!
> I took your advise and just returned the length of the input slice (if
> not error) and it worked!
> The strange thing is how this all just started happening with the
> conforming to Go1. The Write methods haven't changed in this library.
> [...]
> Those comments are where I applied the suggested fix that now works.
> It does indeed modify the buffer before its written, causing the
> length to mismatch for the Buffer.WriteTo
> But strangely this never crashed it in the past.

Suppose the buffer wants to send 1000 bytes, and due to a timeout,
only 500 bytes could be processed, and due to transformations you
return 600. How does the buffer know it has to advance by 500 bytes?

Rémy.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kyle Lemons  
View profile  
 More options Apr 30 2012, 12:41 pm
From: Kyle Lemons <kev...@google.com>
Date: Mon, 30 Apr 2012 09:41:21 -0700
Local: Mon, Apr 30 2012 12:41 pm
Subject: Re: [go-nuts] Re: understanding bytes.Buffer.WriteTo panic

I personally return zero bytes written on error in general.  I haven't seen
any write wrapper code in the stdlib that tries to be smart about
ErrShortWrite or ErrTimeout, so I'm not too concerned, but in general it's
a pain to try to figure out exactly the correlation between how many bytes
were written and the number of input bytes to which that corresponds in a
short write or error condition unless you want to clutter the code (in a
way which is in my opinion) unnecessarily.

On Sun, Apr 29, 2012 at 11:46 PM, Rémy Oudompheng
<remyoudomph...@gmail.com>wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Justin Israel  
View profile  
 More options Apr 30 2012, 3:04 pm
From: Justin Israel <justinisr...@gmail.com>
Date: Mon, 30 Apr 2012 12:04:20 -0700
Local: Mon, Apr 30 2012 3:04 pm
Subject: Re: [go-nuts] Re: understanding bytes.Buffer.WriteTo panic

So if I understand the logic of Buffer.WriteTo in a nutshell, its a panic
to prevent an unchecked transformation in a Write method?
To me, it makes perfect sense what Kyle is suggesting unless you want to
try and get super smart about the numbers. In my specific XHR-POLLING
example in the previous mail, its prepending the various headers before the
source buffer data and writing that. If it fails, I'm fine with considering
it a total failure and returning 0.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kyle Lemons  
View profile  
 More options Apr 30 2012, 3:23 pm
From: Kyle Lemons <kev...@google.com>
Date: Mon, 30 Apr 2012 12:23:26 -0700
Local: Mon, Apr 30 2012 3:23 pm
Subject: Re: [go-nuts] Re: understanding bytes.Buffer.WriteTo panic

Nah, it's a sanity check.  Usually there's a bug somewhere if writes are
writing more bytes than they're supposed to.  If you're just writing a
header, write that and then return the count of the original write.  If
you're adding or removing bytes it's harder, because you're technically
supposed to tell the caller how many of THEIR bytes you wrote, which is
dependent upon (in a difficult-to-calculate way) how many of the
transformed bytes you wrote.

On Mon, Apr 30, 2012 at 12:04 PM, Justin Israel <justinisr...@gmail.com>wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »