rubenlagus / TelegramBots

Java library to create bots using Telegram Bots API
https://telegram.me/JavaBotsApi
MIT License
4.72k stars 1.19k forks source link

TelegramLongPollingCommandBot NPE when command update is received. #716

Open ds64 opened 4 years ago

ds64 commented 4 years ago

The issue is reproduced since TelegramBotExtensions 4.4.0.2, there is a problem that botUsername field of that class is never set before creating an instance of CommandRegistry class. So, botUsername field is always null in CommandRegistry class.

When bot receives update with command in it from Telegram, CommandRegistry.removeUsernameFromCommandIfNeeded method is called. This code in CommandRegistry.java, line 108, produces NPE as botUsername is always null:

return this.allowCommandsWithUsername ? command.replaceAll("(?i)@" + Pattern.quote(this.botUsername), "").trim() : command;

java.lang.NullPointerException: null at java.util.regex.Pattern.quote(Pattern.java:1291) ~[na:1.8.0_191] at org.telegram.telegrambots.extensions.bots.commandbot.commands.CommandRegistry.removeUsernameFromCommandIfNeeded(CommandRegistry.java:126) ~[telegrambotsextensions-4.5.jar:na] at org.telegram.telegrambots.extensions.bots.commandbot.commands.CommandRegistry.executeCommand(CommandRegistry.java:103) ~[telegrambotsextensions-4.5.jar:na] at org.telegram.telegrambots.extensions.bots.commandbot.TelegramLongPollingCommandBot.onUpdateReceived(TelegramLongPollingCommandBot.java:78) ~[telegrambotsextensions-4.5.jar:na] at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_191] at org.telegram.telegrambots.meta.generics.LongPollingBot.onUpdatesReceived(LongPollingBot.java:27) ~[telegrambots-meta-4.5.jar:na] at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:312) ~[telegrambots-4.5.jar:na]

The proposal is to either return TelegramLongPollingCommandBot constructors which receive botUsername as a string, or remove everything "@" character in command without parcing bot username itself.

Chase22 commented 4 years ago

The error is actually caused by the botoptions constructer not setting a bot username https://github.com/rubenlagus/TelegramBots/blob/bd5c5a2f416ed6c556e684f3829671aee1ab3cc7/telegrambots-extensions/src/main/java/org/telegram/telegrambots/extensions/bots/commandbot/TelegramLongPollingCommandBot.java#L68-L71

It needs another parameter to pass in the bot username

ds64 commented 4 years ago

@Chase22, I am gonna check this approach. But even though I know it's deprecated, the public TelegramLongPollingCommandBot(String botUsername) constructor is definitely broken. First, this() is called which creates an instance of CommandRegistry under this bot instance and only after that, the botUsername field is set. So, botUsername field is never set in CommandRegistry instance even if it is passed to constructor. And any update received results in NPE.

Chase22 commented 4 years ago

@ds64 It's definetly a bug. I'll go ahead and make a fix for it. Thanks for pointing it out

Chase22 commented 4 years ago

Fixed in #735