Fix JSON string-array serialization in TgTypeParser (closes #346)#354
Open
Dramex wants to merge 1 commit intoreo7sp:masterfrom
Open
Fix JSON string-array serialization in TgTypeParser (closes #346)#354Dramex wants to merge 1 commit intoreo7sp:masterfrom
Dramex wants to merge 1 commit intoreo7sp:masterfrom
Conversation
parseArray<std::string> call sites passed an identity lambda that returned the raw string unchanged, producing `[a,b]` instead of `["a","b"]`. The resulting invalid JSON broke sticker creation via createNewStickerSet / addStickerToSet (emoji_list and keywords were serialized as naked identifier lists) and Api::setWebhook (allowed_updates missing element quotes). Added a private appendStringArrayToJson helper that emits `"name":["escaped","values"],` directly, escaping each element with StringTools::escapeJsonString. Replaced the seven broken call sites in TgTypeParser (WebhookInfo.allowed_updates, Chat.active_usernames, Giveaway.country_codes, InputSticker.emoji_list, InputSticker.keywords, and both PassportElementError file_hashes variants) and fixed the one remaining lambda site in Api::setWebhook to match the pattern already used by the other Api.cpp call sites. Added three regression tests covering InputSticker serialization. Closes reo7sp#346
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #346.
The bug
Seven call sites passed
parseArray<std::string>an identity lambda:The identity lambda produces
[smile,heart](unquoted identifiers) instead of["smile","heart"]. That's not valid JSON, and @BloodRedTape confirmed in the issue thread that sticker creation is broken because of it. The same pattern exists inApi::setWebhookforallowed_updates.The fix
Added a private helper in
TgTypeParser:which emits
"name":["escaped","values"],directly, running each element throughStringTools::escapeJsonString. It's a no-op when the vector is empty, matching the priorappendToJson(... parseArray(...))behaviour.Replaced the seven broken call sites in
TgTypeParser.cpp:WebhookInfo.allowed_updatesChat.active_usernamesGiveaway.country_codesInputSticker.emoji_list(the issue's primary reproducer)InputSticker.keywordsPassportElementErrorFiles.file_hashesPassportElementErrorTranslationFiles.file_hashesAnd fixed the single analogous site in
Api::setWebhookby aligning its lambda with the pattern the otherApi.cppstring-array sites already use (return "\"" + StringTools::escapeJsonString(s) + "\"").What I did NOT change
I initially experimented with widening
appendToJson(std::string)'s bracket heuristic to recognise[...]as pre-serialized JSON — this would have also fixed latent bugs in other array-wrapping call sites (e.g.parseMessage'sentities). I reverted that because it would regress any field whose value legitimately starts with[and ends with](keyboard-button text like"[CLICK]", captions, etc.). A dedicated helper is safer.Only paths actually used by real Bot API requests are affected by this fix (
setWebhook,createNewStickerSet/addStickerToSetviaparseInputSticker,answerInlineQueryvia the passport-error serializers).Testing
Added
test/tgbot/TgTypeParser.cppwith three regression tests:parseInputStickerEmojiListIsJsonArray— asserts the output contains"emoji_list":["smile","heart"]and not the pre-fix[smile,heart].parseInputStickerEscapesJsonSpecialsInEmoji— asserts inner"and\get properly JSON-escaped.parseInputStickerOmitsEmptyKeywords— preserves prior behaviour where empty arrays are omitted from the output entirely.Local build (Boost 1.90, OpenSSL 3.6, clang 17 on macOS arm64):
(15 pre-existing + 3 new, all passing.)
Also verified end-to-end with a small smoke test: