Taterzens [Fabric]

Taterzens [Fabric]

86.3k Downloads

Taterzens aren't disappearing from the tab list on blanketcon/extremely rare spurious crashes (research post)

quat1024 opened this issue · 2 comments

commented

On blanketcon, taterzens sometimes appear in the tab list with a grey name and [NPC] suffixed (which i believe was added in 6e41c58), but most of the time if you wander around the server for long enough you will collect a bunch of white-named taterzens in the tab list anyways.

Also, you will extremely rarely receive a MalformedJsonException and be kicked from the server. The call comes from net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket#readDisplayName (moj). Most of this issue text is about this crash.

Here is a "packet capture" that I received from the Blanketcon server (made with this mod) that can be fed into ClientboundPlayerInfoPacket#new and replayed to throw the same exception:

0001b4b1d57940804841a9c43b078cda649609416d794d69616c656500087465787475726573a00565776f6749434a306157316c633352686258416949446f674d5459314e4449324e6a51344e6a63304f43774b4943416963484a765a6d6c735a556c6b49694136494349794e7a6b7a5932526a4e6a63334d5441305a54646c4f5751344d574e6d4f5445345a5441324e7a63794f53497343694167496e427962325a706247564f5957316c4969413649434a4262586c4e615746735a5755694c416f6749434a7a6157647559585231636d56535a58463161584a6c5a4349674f694230636e566c4c416f6749434a305a58683064584a6c637949674f69423743694167494341695530744a546949674f694237436941674943416749434a31636d776949446f67496d6830644841364c7939305a58683064584a6c637935746157356c59334a685a6e5175626d56304c33526c65485231636d55764d6d4d314d6d51774e474669597a41335954517a4e545532596d4e6a5a4455324d5441334d7a56684d6a497a4e325a6c5a6a55354f446b7a4e4456694f4463795a6d4d334d474e6c596a42694f575a694f574a6b4e694973436941674943416749434a745a5852685a474630595349674f694237436941674943416749434167496d31765a4756734969413649434a7a62476c7449676f67494341674943423943694167494342394c416f6749434167496b4e425545556949446f6765776f67494341674943416964584a734969413649434a6f644852774f69387664475634644856795a584d7562576c755a574e7959575a304c6d356c644339305a58683064584a6c4c7a497a4e44426a4d4755774d32526b4d6a52684d5446694d5456684f47497a4d324d795954646c4f57557a4d6d4669596a49774e5446694d6a51344d575177596d45335a47566d5a44597a4e574e684e3245354d7a4d694369416749434239436941676651703901ac05565276784d64466572556a3753706f53584b383846586c4a71654661745873376a5a6a5653597176495439757971546f51536c706473686d64666e4a4e326879544458374a4f70416a4f784f794f74334e556168455267664e2b717264635a557566344c444461426456553570686f75564d384b364d38446667625855414b45503433546b487a3477313444567543313549634f7847587553597a4943734b353841644c627466306c64504937514136497671626d67577946727252722f5147317761397071374466776b694771436c304e54686a4f4e446f524d37797958625073485841743443553673533846525653766e42493668446742355a46644b7042436e47373975546e686858452f716f4659516d58387a64536b63794253596b796d42587364552b42323333586e6a7257494242694b5746652b32486470485165546f4a4d337978446b6a3537513968423948597a6b6c424c6f44694179503176682f7079514349756f343236397147694948322b496a39477176567a444c722b59574c6b677a6249615156617433717345775832774c70744242622b4e7752717069514d6f615843422b6e666e3042796e67723453482f464339696c2f2f6737356f3363347162674a385138504379504e63685179436e53464457515168703464556752355732325959365a356868365a5768325a6b2f62707666793757564d3856324b6846344f6f324f62336a765732547147314350556a555559766f306e55436f2b37795752363168544b705348417863364d5862716c7a70594a6a6d6d4539417354475369432f6f5348764c4d594330347578646e6251577177395961343239616d7575615256557661395a4c674b774c6b592b76337a613652786350695050765358726a3264712f3867364874726e6735324f754f583375507a6f362b596e424839765339513d000001147b2274657874223a22416d794d69616c6565227d

readDisplayName calls FriendlyByteBuf#readComponent, which reads the string tures��ewogICJ0aW1lc3RhbXAiIDogMTY1NDI2NjQ4Njc0OCwKICAicHJvZmlsZUlkIiA6ICIyNzkzY2RjNjc3MTA0ZTdlOWQ4MWNmOTE4ZTA2NzcyOSIsC and tries to feed it into Component.Serializer.fromJson, which obviously doesn't work. But the string is suspiciously alphabetic; base64decoding the stuff after tures\U0003 reveals:

{
  "timestamp" : 1654266486748,
  "profileId" : "2793cdc677104e7e9d81cf918e067729",

which looks like a fragment of (very well-formatted, I didn't pretty-print that, lol) game profile json. 2793cdc677104e7e9d81cf918e067729 is the UUID of AmyMialee.

This appears to be a packet with a GameProfile that says it has 0 properties but actually has 1. Execution eventually flows into net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket.Action#read, which calls FriendlyByteBuf#readWithCount, which calls readVarInt, to determine the number of properties. Using a debugger to change the return value of readVarInt from 0 to 1 caused readWithCount to consume the additional blob of base64-json-whatever and fixed the crash when decoding the packet. Replaying the packet added a user named AmyMialee to my tab list.

So now the question is, why is the packet being sent in this broken state.

commented

Thanks for the info! That's really well described.

commented

I think this has been succesfully fixed. I'll wait a little more before closing, if any new reports arrive.