Skip to content

Commit 3c0f25d

Browse files
committed
all: add some safety for client being nil
1 parent 4dcaa22 commit 3c0f25d

13 files changed

+64
-6
lines changed

appstate.go

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ import (
2424
// FetchAppState fetches updates to the given type of app state. If fullSync is true, the current
2525
// cached state will be removed and all app state patches will be re-fetched from the server.
2626
func (cli *Client) FetchAppState(name appstate.WAPatchName, fullSync, onlyIfNotSynced bool) error {
27+
if cli == nil {
28+
return ErrClientIsNil
29+
}
2730
cli.appStateSyncLock.Lock()
2831
defer cli.appStateSyncLock.Unlock()
2932
if fullSync {
@@ -347,6 +350,9 @@ func (cli *Client) requestAppStateKeys(ctx context.Context, rawKeyIDs [][]byte)
347350
//
348351
// cli.SendAppState(appstate.BuildMute(targetJID, true, 24 * time.Hour))
349352
func (cli *Client) SendAppState(patch appstate.PatchInfo) error {
353+
if cli == nil {
354+
return ErrClientIsNil
355+
}
350356
version, hash, err := cli.Store.AppState.GetAppStateVersion(string(patch.Type))
351357
if err != nil {
352358
return err

client.go

+20-3
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,9 @@ func (cli *Client) closeSocketWaitChan() {
371371
}
372372

373373
func (cli *Client) getOwnID() types.JID {
374+
if cli == nil {
375+
return types.EmptyJID
376+
}
374377
id := cli.Store.ID
375378
if id == nil {
376379
return types.EmptyJID
@@ -379,6 +382,9 @@ func (cli *Client) getOwnID() types.JID {
379382
}
380383

381384
func (cli *Client) WaitForConnection(timeout time.Duration) bool {
385+
if cli == nil {
386+
return false
387+
}
382388
timeoutChan := time.After(timeout)
383389
cli.socketLock.RLock()
384390
for cli.socket == nil || !cli.socket.IsConnected() || !cli.IsLoggedIn() {
@@ -398,6 +404,9 @@ func (cli *Client) WaitForConnection(timeout time.Duration) bool {
398404
// Connect connects the client to the WhatsApp web websocket. After connection, it will either
399405
// authenticate if there's data in the device store, or emit a QREvent to set up a new link.
400406
func (cli *Client) Connect() error {
407+
if cli == nil {
408+
return ErrClientIsNil
409+
}
401410
cli.socketLock.Lock()
402411
defer cli.socketLock.Unlock()
403412
if cli.socket != nil {
@@ -444,7 +453,7 @@ func (cli *Client) Connect() error {
444453

445454
// IsLoggedIn returns true after the client is successfully connected and authenticated on WhatsApp.
446455
func (cli *Client) IsLoggedIn() bool {
447-
return cli.isLoggedIn.Load()
456+
return cli != nil && cli.isLoggedIn.Load()
448457
}
449458

450459
func (cli *Client) onDisconnect(ns *socket.NoiseSocket, remote bool) {
@@ -508,6 +517,9 @@ func (cli *Client) autoReconnect() {
508517
// IsConnected checks if the client is connected to the WhatsApp web websocket.
509518
// Note that this doesn't check if the client is authenticated. See the IsLoggedIn field for that.
510519
func (cli *Client) IsConnected() bool {
520+
if cli == nil {
521+
return false
522+
}
511523
cli.socketLock.RLock()
512524
connected := cli.socket != nil && cli.socket.IsConnected()
513525
cli.socketLock.RUnlock()
@@ -519,7 +531,7 @@ func (cli *Client) IsConnected() bool {
519531
// This will not emit any events, the Disconnected event is only used when the
520532
// connection is closed by the server or a network error.
521533
func (cli *Client) Disconnect() {
522-
if cli.socket == nil {
534+
if cli == nil || cli.socket == nil {
523535
return
524536
}
525537
cli.socketLock.Lock()
@@ -544,7 +556,9 @@ func (cli *Client) unlockedDisconnect() {
544556
// Note that this will not emit any events. The LoggedOut event is only used for external logouts
545557
// (triggered by the user from the main device or by WhatsApp servers).
546558
func (cli *Client) Logout() error {
547-
if cli.MessengerConfig != nil {
559+
if cli == nil {
560+
return ErrClientIsNil
561+
} else if cli.MessengerConfig != nil {
548562
return errors.New("can't logout with Messenger credentials")
549563
}
550564
ownID := cli.getOwnID()
@@ -728,6 +742,9 @@ func (cli *Client) handlerQueueLoop(ctx context.Context) {
728742
}
729743

730744
func (cli *Client) sendNodeAndGetData(node waBinary.Node) ([]byte, error) {
745+
if cli == nil {
746+
return nil, ErrClientIsNil
747+
}
731748
cli.socketLock.RLock()
732749
sock := cli.socket
733750
cli.socketLock.RUnlock()

errors.go

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
// Miscellaneous errors
1818
var (
19+
ErrClientIsNil = errors.New("client is nil")
1920
ErrNoSession = errors.New("can't encrypt message for device: no signal session established")
2021
ErrIQTimedOut = errors.New("info query timed out")
2122
ErrNotConnected = errors.New("websocket not connected")

mediaconn.go

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ func (mc *MediaConn) Expiry() time.Time {
4141
}
4242

4343
func (cli *Client) refreshMediaConn(force bool) (*MediaConn, error) {
44+
if cli == nil {
45+
return nil, ErrClientIsNil
46+
}
4447
cli.mediaConnLock.Lock()
4548
defer cli.mediaConnLock.Unlock()
4649
if cli.mediaConnCache == nil || force || time.Now().After(cli.mediaConnCache.Expiry()) {

msgsecret.go

+6
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ type messageEncryptedSecret interface {
8383
}
8484

8585
func (cli *Client) decryptMsgSecret(msg *events.Message, useCase MsgSecretType, encrypted messageEncryptedSecret, origMsgKey *waCommon.MessageKey) ([]byte, error) {
86+
if cli == nil {
87+
return nil, ErrClientIsNil
88+
}
8689
pollSender, err := getOrigSenderFromKey(msg, origMsgKey)
8790
if err != nil {
8891
return nil, err
@@ -102,6 +105,9 @@ func (cli *Client) decryptMsgSecret(msg *events.Message, useCase MsgSecretType,
102105
}
103106

104107
func (cli *Client) encryptMsgSecret(chat, origSender types.JID, origMsgID types.MessageID, useCase MsgSecretType, plaintext []byte) (ciphertext, iv []byte, err error) {
108+
if cli == nil {
109+
return nil, nil, ErrClientIsNil
110+
}
105111
ownID := cli.getOwnID()
106112
if ownID.IsEmpty() {
107113
return nil, nil, ErrNotLoggedIn

newsletter.go

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ func (cli *Client) NewsletterSubscribeLiveUpdates(ctx context.Context, jid types
4040
//
4141
// This is not the same as marking the channel as read on your other devices, use the usual MarkRead function for that.
4242
func (cli *Client) NewsletterMarkViewed(jid types.JID, serverIDs []types.MessageServerID) error {
43+
if cli == nil {
44+
return ErrClientIsNil
45+
}
4346
items := make([]waBinary.Node, len(serverIDs))
4447
for i, id := range serverIDs {
4548
items[i] = waBinary.Node{

pair-code.go

+3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ func generateCompanionEphemeralKey() (ephemeralKeyPair *keys.KeyPair, ephemeralK
8787
//
8888
// See https://faq.whatsapp.com/1324084875126592 for more info
8989
func (cli *Client) PairPhone(phone string, showPushNotification bool, clientType PairClientType, clientDisplayName string) (string, error) {
90+
if cli == nil {
91+
return "", ErrClientIsNil
92+
}
9093
ephemeralKeyPair, ephemeralKey, encodedLinkingCode := generateCompanionEphemeralKey()
9194
phone = notNumbers.ReplaceAllString(phone, "")
9295
if len(phone) <= 6 {

privacysettings.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (cli *Client) TryFetchPrivacySettings(ignoreCache bool) (*types.PrivacySett
4242
// GetPrivacySettings will get the user's privacy settings. If an error occurs while fetching them, the error will be
4343
// logged, but the method will just return an empty struct.
4444
func (cli *Client) GetPrivacySettings() (settings types.PrivacySettings) {
45-
if cli.MessengerConfig != nil {
45+
if cli == nil || cli.MessengerConfig != nil {
4646
return
4747
}
4848
settingsPtr, err := cli.TryFetchPrivacySettings(false)

qrchan.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,9 @@ func (qrc *qrChannel) handleEvent(rawEvt interface{}) {
159159
// The last value to be emitted will be a special event like "success", "timeout" or another error code
160160
// depending on the result of the pairing. The channel will be closed immediately after one of those.
161161
func (cli *Client) GetQRChannel(ctx context.Context) (<-chan QRChannelItem, error) {
162-
if cli.IsConnected() {
162+
if cli == nil {
163+
return nil, ErrClientIsNil
164+
} else if cli.IsConnected() {
163165
return nil, ErrQRAlreadyConnected
164166
} else if cli.Store.ID != nil {
165167
return nil, ErrQRStoreContainsID

request.go

+3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ type infoQuery struct {
106106
}
107107

108108
func (cli *Client) sendIQAsyncAndGetData(query *infoQuery) (<-chan *waBinary.Node, []byte, error) {
109+
if cli == nil {
110+
return nil, nil, ErrClientIsNil
111+
}
109112
if len(query.ID) == 0 {
110113
query.ID = cli.generateRequestID()
111114
}

send.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import (
4040
// msgID := cli.GenerateMessageID()
4141
// cli.SendMessage(context.Background(), targetJID, &waProto.Message{...}, whatsmeow.SendRequestExtra{ID: msgID})
4242
func (cli *Client) GenerateMessageID() types.MessageID {
43-
if cli.MessengerConfig != nil {
43+
if cli != nil && cli.MessengerConfig != nil {
4444
return types.MessageID(strconv.FormatInt(GenerateFacebookMessageID(), 10))
4545
}
4646
data := make([]byte, 8, 8+20+16)
@@ -167,6 +167,10 @@ type SendRequestExtra struct {
167167
// field in incoming message events to figure out what it contains is also a good way to learn how to
168168
// send the same kind of message.
169169
func (cli *Client) SendMessage(ctx context.Context, to types.JID, message *waE2E.Message, extra ...SendRequestExtra) (resp SendResponse, err error) {
170+
if cli == nil {
171+
err = ErrClientIsNil
172+
return
173+
}
170174
var req SendRequestExtra
171175
if len(extra) > 1 {
172176
err = errors.New("only one extra parameter may be provided to SendMessage")

sendfb.go

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ func (cli *Client) SendFBMessage(
4747
metadata *waMsgApplication.MessageApplication_Metadata,
4848
extra ...SendRequestExtra,
4949
) (resp SendResponse, err error) {
50+
if cli == nil {
51+
err = ErrClientIsNil
52+
return
53+
}
5054
var req SendRequestExtra
5155
if len(extra) > 1 {
5256
err = errors.New("only one extra parameter may be provided to SendMessage")

user.go

+6
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,9 @@ type UsyncQueryExtras struct {
728728
}
729729

730730
func (cli *Client) usync(ctx context.Context, jids []types.JID, mode, context string, query []waBinary.Node, extra ...UsyncQueryExtras) (*waBinary.Node, error) {
731+
if cli == nil {
732+
return nil, ErrClientIsNil
733+
}
731734
var extras UsyncQueryExtras
732735
if len(extra) > 1 {
733736
return nil, errors.New("only one extra parameter may be provided to usync()")
@@ -844,6 +847,9 @@ func (cli *Client) UpdateBlocklist(jid types.JID, action events.BlocklistChangeA
844847
},
845848
}},
846849
})
850+
if err != nil {
851+
return nil, err
852+
}
847853
list, ok := resp.GetOptionalChildByTag("list")
848854
if !ok {
849855
return nil, &ElementMissingError{Tag: "list", In: "response to blocklist update"}

0 commit comments

Comments
 (0)