Skip to content

Commit

Permalink
Fix #63
Browse files Browse the repository at this point in the history
Logic race condition, if the decode goroutine can run before the caller
can the channel returned might not have a receiver yet and then the
select/default construct will drop the event and close the channel.

The caller then ends up with a zero-value decodedEvent where
decodedEvent.err and decodedEvent.event are both nil which passes the
err check at line 434 and might enter line 440 where decodedEvent.event
is then used as-is with no additional check for it being nil.
  • Loading branch information
Wessie committed Jan 24, 2024
1 parent f477179 commit 819351e
Showing 1 changed file with 4 additions and 15 deletions.
19 changes: 4 additions & 15 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,35 +150,24 @@ type decodedEvent struct {
}

func (c *ircConn) decode() <-chan decodedEvent {
ch := make(chan decodedEvent)
ch := make(chan decodedEvent, 1)

go func() {
defer close(ch)

line, err := c.io.ReadString(delim)
if err != nil {
select {
case ch <- decodedEvent{err: err}:
default:
}

ch <- decodedEvent{err: err}
return
}

event := ParseEvent(line)
if event == nil {
select {
case ch <- decodedEvent{err: ErrParseEvent{Line: line}}:
default:
}

ch <- decodedEvent{err: ErrParseEvent{Line: line}}
return
}

select {
case ch <- decodedEvent{event: event}:
default:
}
ch <- decodedEvent{event: event}
}()

return ch
Expand Down

0 comments on commit 819351e

Please sign in to comment.