Skip to content

fix: guard type assertions and nil dereferences, release messagePool on exit#9

Merged
yuzone merged 3 commits intomainfrom
fix/panic-risks
Mar 27, 2026
Merged

fix: guard type assertions and nil dereferences, release messagePool on exit#9
yuzone merged 3 commits intomainfrom
fix/panic-risks

Conversation

@yuzone
Copy link
Copy Markdown
Owner

@yuzone yuzone commented Mar 27, 2026

summary

Fix two panic risks and a memory growth issue identified in runtime analysis.

Fix two panic risks and a memory growth issue identified in runtime analysis.

  • Replace unguarded type assertion in getFLBPluginContext with the
    two-value form to avoid panic: interface conversion on unexpected context values.
  • Guard getOffset() (test-only helper) against nil map lookup and
    empty slice access.
  • Add cleanupMsgPool() and call it in FLBPluginExitCtx to delete
    messagePool entries for the config's descriptor tree on shutdown, preventing
    unbounded memory growth across init/exit cycles.

yuzone added 3 commits March 28, 2026 00:54
FLBPluginGetContext returns interface{}. The previous code used an
unguarded type assertion .(int) which panics if the stored value is
not an int (e.g. when FlushCtx is called for an instance whose Init
never completed successfully).

Replace with the two-value form and log a warning on mismatch,
returning 0 so the subsequent configMap lookup fails gracefully.
configMap[id] returns nil when the id is not registered. The previous
code dereferenced config unconditionally, causing a panic.

Add ok-pattern check on the map lookup and a bounds check on the
stream slice before accessing index 0.
…nded growth

messagePool is a global sync.Map keyed by protoreflect.MessageDescriptor
pointer identity. Entries are created lazily on the first Flush call for
each descriptor and were never removed, so descriptor objects (and their
associated *dynamicpb.Message caches) could not be GC'd after a config
was torn down.

Add cleanupMsgPool() which traverses the full descriptor tree rooted at
a given MessageDescriptor and calls sync.Map.Delete for each node,
including nested STRUCT sub-message descriptors. Call it at the end of
FLBPluginExitCtx so that each config's pool entries are released when
the output instance is shut down.

Add TestCleanupMsgPool covering flat and nested schemas to verify that
both the top-level and sub-message pool entries are removed after cleanup.
@yuzone yuzone merged commit db717d2 into main Mar 27, 2026
1 check passed
@yuzone yuzone deleted the fix/panic-risks branch March 27, 2026 16:21
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