Giter Site home page Giter Site logo

lrstanley / girc Goto Github PK

View Code? Open in Web Editor NEW
136.0 136.0 12.0 561 KB

:bomb: girc is a flexible IRC library for Go :ok_hand:

Home Page: https://pkg.go.dev/github.com/lrstanley/girc

License: MIT License

Go 100.00%
ctcp go golang irc irc-client ircv3 library sasl

girc's Introduction

header

πŸ‘‹, I'm @lrstanley, and this is my GitHub profile, where I frequently publish my open-source projects. I hope some of them can be beneficial to you or others. If you like any projects, please give some of them a ⭐, it would be much appreciated!

  • 🌎 Originally from Michigan, US, I am currently located in North Carolina, US.
  • πŸš€ I am working on many projects, primarily revolving around tools to help improve the experience for other developers.
  • πŸ”— Take a look at my personal website, https://liam.sh.
  • πŸ“ Browse some of the blog posts I have written here.
  • πŸ™‹β€β™‚οΈ Want to chat? Check out the Bytecord discord server, we talk programming, technology, 3d printers, games, etc.
  • ❀️ Feeling generous? Sponsor me!
  • πŸ—οΈ Security concern with one of my repositories? Every repo has a SECURITY.md (example).

πŸ“Œ A note on archived repositories

I have a lot of repositories that have been developed over the years, many of them are related to something I would be working on at the time, and I have transitioned to another tool or similar, or simply there wasn't enough desire from others to allow me to continue working on the projects/keeping it active. As such, I mark repositories as archived to make it obvious that there is a lack of attention being put in place on that project. This does not mean it's abandoned forever. If the need to maintain it resurges or I start working on the project again, I will unarchive it.


girc's People

Contributors

42wim avatar lrstanley avatar nmeum avatar pmaynard avatar puffrfish avatar wessie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

girc's Issues

execLoop and sendLoop not getting closed if network connection is low-quality

It appears that if a low-quality network connection (e.g. being behind a Whonix Tor transproxy) is being used, the execLoop and/or sendLoop goroutines aren't reliably being closed properly after a disconnect.

Originally reported at 42wim/matterbridge#1743 (detailed logs are in that issue) ; @42wim suggested that I report it here. I'm happy to help with trying to narrow down the bug, e.g. by collecting more detailed logs, but my ability to help may be limited since I'm not the author of the affected software. In any event please let me know what I can do to help get this fixed.

feature: IRCv3 `setname`

✨ Describe the feature you'd like

Ref: IRCv3 setname

Motivation

Historically, a user’s realname could only be set on the initial connection handshake. However, multiple IRC servers have provided independent non-standard commands to update the realname without reconnecting. This specification describes a standardised behaviour based on these existing implementations.

Once support is added, the IRCv3 Library Support page needs to be updated to include these features.

sasl on freenode doesn't work

I'm trying to connect to freenode with SASL, but it isn't working.
The CAP LS doesn't get any response.
It looks like freenode expects CAP LS before NICK/USER
When I moved c.listCAP() in conn.go before the NICK/USER writes it works.

feature: Netsplit detection heuristic

✨ Describe the feature you'd like

Presently, girc does not include any heuristics to detect netsplits. Therefore, after a netsplit, the client may remain on the splitted network. I think it would be handy if girc would detect netsplits and attempt a reconnect in the case of a netsplit.

🌧 Is your feature request related to a problem?

No.

πŸ”Ž Describe alternatives you've considered

N/A

⚠ If implemented, do you think this feature will be a breaking change to users?

No

βš™ Additional context

For reference, the IRC netsplit detection heuristic is available here: https://github.com/irssi/irssi/blob/master/src/irc/core/netsplit.c

🀝 Requirements

  • I have confirmed that someone else has not submitted a similar feature request.
  • If implemented, I believe this feature will help others, in addition to solving my problems.
  • I have looked into alternative solutions to the best of my ability.
  • (optional) I would be willing to contribute to testing this feature if implemented, or making a PR to implement this functionality.

bug: Twitch connection fails with "connection failed EOF"

🌧 Describe the problem

Following 42wim/matterbridge#2037 commit 8240917 causes matterbridge not connect to twitch.tv on irc protocol properly.

Using matterbridge-1.26.0-linux-64bit and this config

[irc.tv]
Password="mytokenwasreplacedofc"
Nick="Somenick"
Server="irc.chat.twitch.tv:6697"
UseTLS=true
RemoteNickFormat="<{NICK}> "
Charset="utf-8"

I get this error:

time="2023-04-04T11:26:18Z" level=error msg="disconnect: error: EOF" prefix=irc
time="2023-04-04T11:26:18Z" level=fatal msg="Starting gateway failed: Bridge irc.tv failed to start: connection failed EOF" prefix=main

Downgrading to matterbridge-1.25.2-linux-64bit does not produce the same error. This only difference between those two versions is the commit mentioned above. The matterbridge folks advised me how to compile without this commit: 42wim/matterbridge#2037 (comment) and it worked as expected.

The same matterbridge connects to irc.libera.chat without problems, so it seems something twitch specific.

Here you can see a successful join to irc.libera.chat and then starts the join to twitch. Matterbridge with --debug option:

time="2023-04-06T21:56:28Z" level=debug msg=""CLIENT_CONNECTED irc.libera.chat:6667"" func=handleOther file="bridge/irc/handlers.go:170" prefix=irc
time="2023-04-06T21:56:32Z" level=info msg="Connection succeeded" func=Connect file="bridge/irc/irc.go:107" prefix=irc
time="2023-04-06T21:56:32Z" level=info msg="irc.yl: joining #your-land-web (ID: #your-land-webirc.yl)" func=joinChannels file="bridge/bridge.go:77" prefix=irc
time="2023-04-06T21:56:32Z" level=debug msg=""@time=2023-04-06T21:56:26.913Z :YL MODE YL +iw"" func=handleOther file="bridge/irc/handlers.go:170" prefix=irc
time="2023-04-06T21:56:32Z" level=info msg="irc.yl: joining #your-land-chat (ID: #your-land-chatirc.yl)" func=joinChannels file="bridge/bridge.go:77" prefix=irc
time="2023-04-06T21:56:32Z" level=info msg="irc.yl: joining #your-flight-chat (ID: #your-flight-chatirc.yl)" func=joinChannels file="bridge/bridge.go:77" prefix=irc
time="2023-04-06T21:56:32Z" level=info msg="irc.yl: joining #your-land-dev (ID: #your-land-devirc.yl)" func=joinChannels file="bridge/bridge.go:77" prefix=irc
time="2023-04-06T21:56:32Z" level=info msg="Starting bridge: irc.tv " func=Start file="gateway/router.go:75" prefix=router
time="2023-04-06T21:56:32Z" level=info msg="Connecting irc.chat.twitch.tv:6697" func=Connect file="bridge/irc/irc.go:81" prefix=irc
time="2023-04-06T21:56:32Z" level=debug msg="setting pingdelay to 1m0s" func=getClient file="bridge/irc/irc.go:306" prefix=irc
time="2023-04-06T21:56:32Z" level=debug msg="handle girc.Event{Source:(*girc.Source)(0xc000c2e450), Tags:girc.Tags{"time":"2023-04-06T21:56:32.231Z"}, Timestamp:time.Date(2023, time.April, 6, 21, 56, 32, 231000000, time.Local), Command:"JOIN", Params:[]string{"#your-land-web", "*", "YL"}, Sensitive:false, Echo:false}" func=handleJoinPart file="bridge/irc/handlers.go:117" prefix=irc
time="2023-04-06T21:56:32Z" level=debug msg="333: Topic set by Alias [~Alias@user/alias] [2022-04-04 21:48:03 +0000 UTC]" func=handleTopicWhoTime file="bridge/irc/handlers.go:264" prefix=irc
time="2023-04-06T21:56:32Z" level=debug msg="handle girc.Event{Source:(*girc.Source)(0xc000a171a0), Tags:girc.Tags{"time":"2023-04-06T21:56:32.232Z"}, Timestamp:time.Date(2023, time.April, 6, 21, 56, 32, 232000000, time.Local), Command:"JOIN", Params:[]string{"#your-land-chat", "*", "YL"}, Sensitive:false, Echo:false}" func=handleJoinPart file="bridge/irc/handlers.go:117" prefix=irc
time="2023-04-06T21:56:32Z" level=debug msg="handle girc.Event{Source:(*girc.Source)(0xc000b40690), Tags:girc.Tags{"time":"2023-04-06T21:56:32.233Z"}, Timestamp:time.Date(2023, time.April, 6, 21, 56, 32, 233000000, time.Local), Command:"JOIN", Params:[]string{"#your-flight-chat", "*", "YL"}, Sensitive:false, Echo:false}" func=handleJoinPart file="bridge/irc/handlers.go:117" prefix=irc
time="2023-04-06T21:56:32Z" level=debug msg="handle girc.Event{Source:(*girc.Source)(0xc000b40f60), Tags:girc.Tags{"time":"2023-04-06T21:56:32.233Z"}, Timestamp:time.Date(2023, time.April, 6, 21, 56, 32, 233000000, time.Local), Command:"JOIN", Params:[]string{"#your-land-dev", "*", "YL"}, Sensitive:false, Echo:false}" func=handleJoinPart file="bridge/irc/handlers.go:117" prefix=irc
time="2023-04-06T21:56:32Z" level=debug msg=""CLIENT_INIT irc.chat.twitch.tv:6697"" func=handleOther file="bridge/irc/handlers.go:170" prefix=irc
time="2023-04-06T21:56:32Z" level=debug msg=""CLIENT_DISCONNECTED irc.chat.twitch.tv:6697"" func=handleOther file="bridge/irc/handlers.go:170" prefix=irc
time="2023-04-06T21:56:32Z" level=error msg="disconnect: error: EOF" func=doConnect file="bridge/irc/irc.go:194" prefix=irc
time="2023-04-06T21:56:32Z" level=fatal msg="Starting gateway failed: Bridge irc.tv failed to start: connection failed EOF" func=main file="matterbridge.go:66" prefix=main

This is the same log as in 42wim/matterbridge#2037 (comment)

β›… Expected behavior

Connection to twitch.tv successful

πŸ”„ Minimal reproduction

Run matterbridge 1.26.0 with the config mentioned above

πŸ’  Version: girc

8240917

πŸ–₯ Version: Operating system

linux/debian

βš™ Additional context

Workaround available: Downgrade to matterbridge-1.25.2-linux-64bit: version: 1.25.2 42wim/matterbridge@20f841c or removal of commit 8240917

Not urgent

Selfcontrolled, we can do all kinds of tests with it

Touches #54

Blocks 42wim/matterbridge#2037

For my reference 4114

🀝 Requirements

feature: IRCv3 `WHOX`

✨ Describe the feature you'd like

Ref: IRCv3 WHOX

Introduction

The WHOX extension allows clients to request additional fields in the WHO response (e.g. account name) or omit default fields (e.g. username and hostname).

Once support is added, the IRCv3 Library Support page needs to be updated to include these features.

Race Condition in ping/pong handler

After making a simple client and building with -race, a data race was found rather fast involving the ping/pong handling code.

==================
WARNING: DATA RACE
Read at 0x00c0420f2090 by goroutine 14:
  github.com/lrstanley/girc.(*Client).pingLoop()
      F:/goenv/src/github.com/lrstanley/girc/conn.go:546 +0x5b0

Previous write at 0x00c0420f2090 by goroutine 53:
  github.com/lrstanley/girc.handlePONG()
      F:/goenv/src/github.com/lrstanley/girc/builtin.go:116 +0x91
  github.com/lrstanley/girc.HandlerFunc.Execute()
      F:/goenv/src/github.com/lrstanley/girc/handler.go:67 +0x77
  github.com/lrstanley/girc.(*Caller).exec.func1()
      F:/goenv/src/github.com/lrstanley/girc/handler.go:231 +0x476

Goroutine 14 (running) created at:
  github.com/lrstanley/girc.(*Client).internalConnect()
      F:/goenv/src/github.com/lrstanley/girc/conn.go:284 +0x3b7
  github.com/lrstanley/girc.(*Client).Connect()
      F:/goenv/src/github.com/lrstanley/girc/conn.go:184 +0x4c
  main.main()
      F:/goenv/src/github.com/R-a-dio/valkyrie/cmd/hanyuu/main.go:33 +0x195

Goroutine 53 (finished) created at:
  github.com/lrstanley/girc.(*Caller).exec()
      F:/goenv/src/github.com/lrstanley/girc/handler.go:209 +0x276
  github.com/lrstanley/girc.(*Client).RunHandlers()
      F:/goenv/src/github.com/lrstanley/girc/handler.go:45 +0x40a
  github.com/lrstanley/girc.(*Client).execLoop()
      F:/goenv/src/github.com/lrstanley/girc/client.go:345 +0x18a
==================

Make CTCP handlers optional

The default CTCP handlers are currently registered unconditionally in client.New. The CTCP handlers disclose quite a few things, e.g. current Time (through handleCTCPTime) and operating system, architecture and girc version (through handleCTCPVersion).

IMHO it would be nice if these handlers could be disabled. For instance through a new Config option.

sasl on irc.rizon.net doesn't work

I haven't debugged it any further, but it seems SASL doesn't work on irc.rizon.net
I'm getting :irc.rizon.io 904 user :SASL authentication failed

Implement RPL_CREATIONTIME

First off, love girc. I have a ridiculous fork of it with a lot of wacky changes and have gotten pretty familiar with this masterpiece of yours.

Anyway, you're missing definition and handling of code 329 AKA RPL_CREATIONTIME. (details below)

Details

RPL_CREATIONTIME (329)

<client> <channel> <creationtime>

Sent to a client to inform them of the creation time of a channel. is the name of the channel. is a unix timestamp representing when the channel was created on the network.


I almost made a PR to add it for you into the definitions. However, after a bit of searching I'm not so sure it's in the RFC(s). Because of this I wasn't sure where exactly you'd want to place it, if at all.

It is however, very prevalent and well-enough documented. It likely should be in constants, and if you're feeling cheeky enough, maybe even handled and stored in the channel state. (this is what I plan on doing with girc-atomic).

Multiple race conditions in the code

Currently running go test -race gives out at least one data race warning, I've personally identified another one in the ping/pong code that writes/reads to the struct variables without synchronization.

There might be more, since I don't know how extensive the current test code is.

DISCONNECTED event handler is never invoked

The documentation states the following:

// occurs when we're disconnected from the server (user-requested or not)
DISCONNECTED   = "CLIENT_DISCONNECTED"

However, the code to invoke handlers registered for this constant seems to have been removed in 4951996. The DISCONNECTED constant is currently not used anywhere in the code base.

Not sure if you simply forgot removing the constant in 4951996...

feature: IRCv3 Labeled Responses

✨ Describe the feature you'd like

Ref: IRCv3 Labeled Responses

Introduction

This specification adds a new message tag sent by clients and repeated by servers to correlate responses with a specific request.

Motivation

Certain client actions can result in responses from the server that vary in interpretation depending on how they were triggered, or otherwise lack a robust way to correlate with local state. Clients have historically needed to keep track of additional local state and/or apply comparison heuristics to server responses to correlate these appropriately.

Labeled responses enable a much simpler form of correlation by using a single id attached to a client request and repeated by the server in its response.

Additionally, labeled responses allow bouncers with multiple connected clients to direct responses (such as WHOIS queries or error messages, see examples) to the correct recipient.

Once support is added, the IRCv3 Library Support page needs to be updated to include these features.

Implement splitting of long messages?

From RFC 2812:

IRC messages are always lines of characters terminated with a CR-LF (Carriage Return - Line Feed) pair, and these messages SHALL NOT exceed 512 characters in length, counting all characters including the trailing CR-LF.

As I understand it, this is a restriction which applies to messages sent by the server. The client needs to make sure that sent client messages do not result in server messages which exceed this limit. This requires some heuristics to determine the length of the resulting server message for a given client message. Which, in turn, requires calculating the maximum nick and host length et cetera. I personally think that this is a major defect of the IRC protocol itself as it requires implementing "dodgy hacks for every single command" which may exceed this message length. As such, this has also been discussed by the IRv3 working group [1].

Short-term it would nice to implement splitting of messages which exceed this limit. For instance, if a PRIVMSG exceeds it, it has to be split into two PRIVMSG commands. I started working on such an implementation in my own IRC client, which uses girc, however I personally think that message splitting would be best implemented in girc itself. What are your thoughts on this?

Existing "message splitting" implementations:

Maybe it would make sense to start with an implementation of message splitting for PRIVMSGs and maybe extend it to other commands afterwards?

Don't store RFC 1459 compliant nick in User struct

The problem with performing ToRFC1459() on the nick before storing it in the User struct is that (among other things) capitalization is lost. So function like client.UserList always return all nicks in lowercase.

I am personally using the values return by channel.UserList for tab completions and to me it is kind of annoying that the capitalization of nicks as shown by event.Pretty() differs from the one suggested by the tab completions I have implemented.

I would suggest that nicks are not stored in an RFC 1459 compliant format since any nick can be made RFC 1459 compliant using the ToRFC1459 function on demand but converting it back to its original format isn't possible.

ability to not send nick in the login process

hey!

I wrote some custom handlers for handling NICK messages and it's related errors, but the internal conflict handlers interfere (resulting in silly things like the name being reset back), and due to the nature of this handler, there is state involved with figuring out a nick conflict (specifically, a number is incremented), meaning it cannot be easily translated to HandleNickCollide.

for this reason I propose that NICK initialnick optionally removed from the initial setup process, letting the user do it after a CONNECTED event, but still keep the internal nick tracking

Use of struct{} instead of string where value is ignored

I have stumbled upon the code here, where you are using string (as in map[string][]string) and nil, instead of struct{} and struct{}{}. From a quick glance I cannot see you using the value anywhere, and using struct{} would communicate this intent better, therefore making the codebase slightly cleaner, and additionally it would consume less memory, but this memory consumption is negligible either way.

From:

var possibleCap = map[string][]string{
  "account-notify": nil,
[...]
}

to:

var possibleCap = map[string]struct{}{
  "account-notify": struct{}{},
[...]
}

You may also like to compare the assembly output: https://go.godbolt.org/z/4IMjlE

bug: newlines are removed instead of changed to a space

🌧 Describe the problem

When calling Cmd.Message() with a message containing a newline, the newline is stripped, which smashes words together.

β›… Expected behavior

The newline should be replaced with a space, instead of just stripped

πŸ”„ Minimal reproduction

Call Cmd.Message("#foo", "example\nmessage") and observe that the resulting message is "examplemessage" instead of "example message"

πŸ’  Version: girc

v0.0.0-20220410132120-49de39aea653

πŸ–₯ Version: Operating system

linux/other

βš™ Additional context

I'm using girc via https://github.com/RITlug/teleirc . When a telegram message contains a newline, the resulting IRC message has this problem. It could be worked around in TeleIRC, but it seemed like girc would be a better place to fix it for everyone.

I'm not sure the best way to handle \r or \r\n - ideally collapsing runs of either to just one space?

🀝 Requirements

Cmd.Part and Cmd.PartMessage attempt to JOIN instead of PART

When using the client commands Part and PartMessage a JOIN will be sent instead of a PART.

client.Cmd.Part("#mychannel", "poof")
client.Cmd.PartMessage("#mychannel", "poof")

debug:19:37:52 conn.go:451: > JOIN #mychannel
debug:19:37:52 conn.go:451: > JOIN #mychannel :poof```

Special treatment of 'trailing' argument in commands is incorrect

The IRC RFC says this about the format of commands:

<params>   ::= <SPACE> [ ':' <trailing> | <middle> <params> ]

<middle>   ::= <Any *non-empty* sequence of octets not including SPACE
               or NUL or CR or LF, the first of which may not be ':'>
<trailing> ::= <Any, possibly *empty*, sequence of octets not including
                 NUL or CR or LF>

and

  2)    After extracting the parameter list, all parameters are equal,
        whether matched by <middle> or <trailing>. <Trailing> is just
        a syntactic trick to allow SPACE within parameter.

In essence, there is no semantic difference between an argument parsed as a 'middle' or one as a 'trailing'. Trailing is simply a syntactic specification to allow the last argument in a command to contain spaces, if so desired.

However, girc doesn't follow this footnote and explicitly encodes 'trailing' as some special kind of command parameter. This is incorrect; if a command has a 'trailing' parameter, this is simply the last parameter of the command. There is no special meaning to it.

This makes the library cumbersome to use at best (since special care must be taken in regards to 'empty trailing', which should not be necessary at all), and broken at worst (since IRCds are within their rights to send commands for which you would 'expect' a trailing argument without one, such as PRIVMSG, or send commands with a trailing argument which you would not expect to have one).

This is IMHO a very huge flaw in the library and should be fixed before it goes 1.0.

feature: IRCv3 Standard Replies

✨ Describe the feature you'd like

Ref: IRCv3 Standard Replies

Introduction

This document specifies the standard FAIL, WARN, and NOTE messages, intended to provide a clean, consistent interface for sending general errors, warnings, and informational messages to clients. Implementers should not need to reserve new numerics for error, warning, or general informational messages, especially as numerics themselves and the mapping of numerics to names can be unclear or conflicting.

The FAIL message indicates a complete failure to process a given command/function, or simply some error about the current session that clients should be aware of.

The WARN message indicates some non-fatal feedback about a given command/function, or some less vital feedback on the current session.

The NOTE message indicates some informational message about a given command/function, or about the current session.

Once support is added, the IRCv3 Library Support page needs to be updated to include these features.

Allow extra characters

Somewhat related to https://github.com/lrstanley/girc/projects/1#card-6997933

Functions like IsValidNick and IsValidUser exist:

girc/format.go

Lines 214 to 241 in 51b8e09

// IsValidNick validates an IRC nickname. Note that this does not validate
// IRC nickname length.
//
// nickname = ( letter / special ) *8( letter / digit / special / "-" )
// letter = 0x41-0x5A / 0x61-0x7A
// digit = 0x30-0x39
// special = 0x5B-0x60 / 0x7B-0x7D
func IsValidNick(nick string) bool {
if len(nick) <= 0 {
return false
}
// Check the first index. Some characters aren't allowed for the first
// index of an IRC nickname.
if (nick[0] < 'A' || nick[0] > '}') && nick[0] != '?' {
// a-z, A-Z, '_\[]{}^|', and '?' in the case of znc.
return false
}
for i := 1; i < len(nick); i++ {
if (nick[i] < 'A' || nick[i] > '}') && (nick[i] < '0' || nick[i] > '9') && nick[i] != '-' {
// a-z, A-Z, 0-9, -, and _\[]{}^|
return false
}
}
return true
}

girc/format.go

Lines 243 to 286 in 51b8e09

// IsValidUser validates an IRC ident/username. Note that this does not
// validate IRC ident length.
//
// The validation checks are much like what characters are allowed with an
// IRC nickname (see IsValidNick()), however an ident/username can:
//
// 1. Must either start with alphanumberic char, or "~" then alphanumberic
// char.
//
// 2. Contain a "." (period), for use with "first.last". Though, this may
// not be supported on all networks. Some limit this to only a single period.
//
// Per RFC:
// user = 1*( %x01-09 / %x0B-0C / %x0E-1F / %x21-3F / %x41-FF )
// ; any octet except NUL, CR, LF, " " and "@"
func IsValidUser(name string) bool {
if len(name) <= 0 {
return false
}
// "~" is prepended (commonly) if there was no ident server response.
if name[0] == '~' {
// Means name only contained "~".
if len(name) < 2 {
return false
}
name = name[1:]
}
// Check to see if the first index is alphanumeric.
if (name[0] < 'A' || name[0] > 'Z') && (name[0] < 'a' || name[0] > 'z') && (name[0] < '0' || name[0] > '9') {
return false
}
for i := 1; i < len(name); i++ {
if (name[i] < 'A' || name[i] > '}') && (name[i] < '0' || name[i] > '9') && name[i] != '-' && name[i] != '.' {
// a-z, A-Z, 0-9, -, and _\[]{}^|
return false
}
}
return true
}

It would be useful if we could abstract this into an interface NickValidator.

My particular use-case is that we have a customised IRC server that allows certain users to use the tilde (~) character β€” discord puppets have a ~d suffix. See qaisjp/go-discord-irc.

Would you be willing to accept a pull request that implements this?

(This would prevent the need to fork your repo.)

bug: crash after reconnecting when not sending a message

🌧 Describe the problem

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0xb23397]

goroutine 4248 [running]:
github.com/lrstanley/girc.(*Client).readLoop(0xc000454a80, {0x1722cb8, 0xc0005704b0})
	/home/allbery/go/pkg/mod/github.com/lrstanley/[email protected]/conn.go:440 +0x297
github.com/lrstanley/girc/internal/ctxgroup.(*Group).Go.func1()
	/home/allbery/go/pkg/mod/github.com/lrstanley/[email protected]/internal/ctxgroup/ctxgroup.go:58 +0x63
created by github.com/lrstanley/girc/internal/ctxgroup.(*Group).Go in goroutine 31
	/home/allbery/go/pkg/mod/github.com/lrstanley/[email protected]/internal/ctxgroup/ctxgroup.go:55 +0x79

This is happening with matterbridge, both latest release and git versions, but doesn't appear to be related directly to matterbridge. It also doesn't appear to be the same problem as #14 because the bridge has been quiescent aside from the reconnect, and the line numbers/traceback differ.

β›… Expected behavior

I expect the IRC client to successfully resume after reconnecting,

πŸ”„ Minimal reproduction

No response

πŸ’  Version: girc

v0.0.0-20230729130341-dd5853a5f1a6

πŸ–₯ Version: Operating system

linux/ubuntu

βš™ Additional context

I have not as yet tried rebuilding matterbridge with the version on pkg.go.dev.
If it matters, the specific Ubuntu release is 22.04.2.

🀝 Requirements

Bad who command

Running this on a test server:

:irc.foonet.com 255 r :I have 2 clients and 0 servers
:irc.foonet.com 265 r 2 2 :Current local users 2, max 2
:irc.foonet.com 266 r 2 2 :Current global users 2, max 2
:irc.foonet.com 375 r :- irc.foonet.com Message of the Day - 
:irc.foonet.com 372 r :- 17/1/2019 0:18
:irc.foonet.com 372 r :- message
:irc.foonet.com 376 r :End of /MOTD command.
:r MODE r :+iwx
JOIN #inout
:[email protected] JOIN #inout * :r
WHO #inout %tacuhnr,1
MODE #inout
:irc.foonet.com 353 r = #inout :[email protected] @[email protected] 
:irc.foonet.com 366 r #inout :End of /NAMES list.
:irc.foonet.com 352 r #inout r 381B2339.5C917854.9C80D685.IP irc.foonet.com r H :0 r

It tries to do a WHO asking for a variable name "WHO #inout %tacuhnr,1"

Look around line 170 in builtin.go but unsure how to fix it.

`

Runtime error when using the client during reconnect

Hi,

I'm using the girc library in one of my projects and just added some code from the girc examples to reconnecting to the IRC server.
This works perfectly fine and when the connection is lost, he reconencts automatically after the given delay. But the problem is, that when a other goroutine tries to call e.g. Cmd.Message() to send something during the time between the connection is lost and girc reconnects, it ends up with a SIGSEGV and crashes. See the attached stacktrace

I'm not sure if this is a library problem of girc or if I should catch this and don't use the client during reconenction.

Please let me know if you need more informations to debug this.

Best regards,
Felix

2018/08/15 22:09:11 Connection to irc.hackint.eu:6667 terminated: timed out waiting for a requested PING response
2018/08/15 22:09:11 Reconnecting to irc.hackint.eu:6667 in 30 seconds...

<other gorouting calls Cmd.Message() at this moment>

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7c03ff]

goroutine 18 [running]:
github.com/lrstanley/girc.(*ircConn).rate(0x0, 0x15, 0x0)
	/home/fleaz/workspace/go/src/github.com/lrstanley/girc/conn.go:411 +0x2f
github.com/lrstanley/girc.(*Client).Send(0xc42018e000, 0xc420310770)
	/home/fleaz/workspace/go/src/github.com/lrstanley/girc/conn.go:389 +0x17d
github.com/lrstanley/girc.(*Commands).Message(0xc42017a030, 0xc420024a24, 0x6, 0xc4203331c0, 0x5)
	/home/fleaz/workspace/go/src/github.com/lrstanley/girc/commands.go:108 +0xf5
main.channelReceiver()
	/home/fleaz/workspace/go/src/github.com/f-breidenstein/CptHook/irc.go:106 +0xe8
created by main.ircConnection
	/home/fleaz/workspace/go/src/github.com/f-breidenstein/CptHook/irc.go:87 +0x339

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.