Skip to content

Tolerate a null file in DelayedFileSource - #3370

Open
FrayxRulez wants to merge 1 commit into
developfrom
delayed-file-source-null
Open

Tolerate a null file in DelayedFileSource#3370
FrayxRulez wants to merge 1 commit into
developfrom
delayed-file-source-null

Conversation

@FrayxRulez

Copy link
Copy Markdown
Collaborator

NullReferenceException — "Object reference not set to an instance of an object", reported by crash telemetry on 12.9.1.0.

0  Telegram.Streams.DelayedFileSource.get_Id
   Telegram/Streams/DelayedFileSource.cs:181
1  Telegram.Streams.DelayedFileSource.GetHashCode
   Telegram/Streams/DelayedFileSource.cs:228
2  System.Collections.Generic.ObjectEqualityComparer`1.GetHashCode
3  Telegram.Controls.AnimatedImagePresentation.GetHashCode
4  Telegram.Controls.AnimatedImageLoader.GetOrCreate
   Telegram/Controls/AnimatedImage.cs:1857
5  Telegram.Controls.AnimatedImage.Load
   Telegram/Controls/AnimatedImage.cs:519
6  Telegram.Controls.AnimatedImage.OnLoaded
   Telegram/Controls/AnimatedImage.cs:122

Cause

A DelayedFileSource built from a sticker whose StickerValue is null ends up with a null _file. That is a supported state everywhere else in the hierarchy — the constructor guards if (file != null), FilePath and IsDownloadingCompleted use _file?., LocalFileSource returns early on a null file, and all four delayed subclasses override Id because their _file starts null. The base Id was the one accessor that dereferenced it unconditionally, and GetHashCode (HashCode.Combine(Id, IsAnimated)) makes it unavoidable as soon as AnimatedImageLoader.GetOrCreate hashes the presentation. The crashing instance is the base class, not a subclass.

EmojiDrawerViewModel deliberately inserts placeholder stickers with a null StickerValue, so this is reachable from the emoji drawer.

Change

  • DelayedFileSource.Id falls back to 0 on a null file, matching LocalFileSource, whose Id is left at 0 for exactly this case.
  • DelayedFileSource.DownloadFile returns early on a null file instead of dereferencing it three times. Subclasses fully override this method to resolve the file themselves, so nothing in that path is lost.
  • EmojiDrawer's "+N" expand path assigns a file source without the StickerValue != null check that its two sibling call sites in the same file already have; added.

Not built — a .NET Native build isn't available here. Both files parse clean under CSharpSyntaxTree.ParseText(...).GetDiagnostics(), which catches syntax errors and nothing more.

🤖 Generated with Claude Code

A sticker with no StickerValue leaves _file null, which every other member
of the hierarchy already supports, so hashing the source crashed on Id.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant