Skip to content

sonic-id3: fix recursive root listing with artists - #213

Merged
fangfufu merged 3 commits into
fangfufu:masterfrom
svfrd:fix_sonic_id3
May 16, 2026
Merged

sonic-id3: fix recursive root listing with artists#213
fangfufu merged 3 commits into
fangfufu:masterfrom
svfrd:fix_sonic_id3

Conversation

@svfrd

@svfrd svfrd commented May 15, 2026

Copy link
Copy Markdown
Contributor

path_to_LinkTable() overwrites populated next_table causing recursive root listing under letter dirs.

The path_to_LinkTable() issue affects NORMAL and SINGLE modes too in principle (it always re-creates the table), but those modes' constructors (LinkTable_new with disk cache 1) are idempotent enough that users don't notice.
In SONIC ID3 mode, sonic_LinkTable_new_id3(0, NULL) is destructive, which is why this bug surfaces there.

Tested with funkhwale subsonic endpoint.

Summary by CodeRabbit

  • Bug Fixes

    • Corrected ID3 index handling so artist listings no longer get lost or duplicated during navigation.
  • Performance

    • Reused existing directory tables to avoid redundant reconstruction, reducing unnecessary work and improving listing stability.
  • Documentation

    • Updated release notes to reflect the fix and related changes.

Review Change Stack

Summary by CodeRabbit

  • Bug Fixes
    • Reuse existing in-memory directory tables to prevent redundant creation, reducing memory leaks and unnecessary I/O when revisiting directories.
    • Improve ID3 index parsing so artist entries are only added to the correct index context, preventing misplaced entries, data loss, and leaked resources during recursive root listings.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a94d65f2-f6e1-432f-afbb-83c68ca7a933

📥 Commits

Reviewing files that changed from the base of the PR and between 4b7472a and f7df2ca.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • src/link.c
  • src/sonic.c
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/link.c
  • src/sonic.c

📝 Walkthrough

Walkthrough

Reuses populated child LinkTables during path resolution and adds explicit ID3 state tracking in Sonic XML parsing; artist entries are routed into the active index table and parsing cleanup is improved.

Changes

State Management for Link and ID3 Index Tables

Layer / File(s) Summary
Directory table reuse in path traversal
src/link.c
path_to_LinkTable() reuses an existing link->next_table when present to avoid reconstructing/overwriting populated child LinkTables during subsequent accesses.
ID3 index state tracking framework
src/sonic.c
Adds id3_current_index_table and an XML_parser_id3_root_end end handler; the handler is registered during sonic_url_to_LinkTable parsing setup, and state is reset before and after parsing (including on errors).
ID3 element routing and artist insertion
src/sonic.c
Removes the "last link added to root" heuristic. <index> sets id3_current_index_table (or frees the index link if name missing). <artist> entries outside an active <index> are ignored with a warning; artist parsing frees link->sonic.id on failure and inserts successful artist links into id3_current_index_table.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A table kept, not thrown away,
Indexes tracked where artists play.
No more guessing which root to send,
Links find their home from start to end.
Happy parsing hops today!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main fix addressing recursive root listing issues with artists in Sonic ID3 mode.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request improves the Subsonic XML parsing logic by explicitly tracking the current index table and reusing existing link tables to prevent incorrect directory listings. It also includes memory cleanup for artist IDs. Feedback highlights a critical thread-safety issue introduced by the use of a static global variable for parser state and a minor style violation regarding missing braces in a conditional block.

Comment thread src/sonic.c
* <index> produces no link or when elements arrive in an unexpected
* order. Track the parent explicitly via an end-element handler.
*/
static LinkTable *id3_current_index_table = NULL;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The use of a static global variable id3_current_index_table to maintain state during XML parsing is not thread-safe. In a multi-threaded environment (as suggested by the use of link_lock in src/link.c), concurrent calls to sonic_url_to_LinkTable using the XML_parser_id3_root handler will lead to race conditions and corrupted parser state.

Consider passing a context structure (containing both the root LinkTable and the current index LinkTable) through the void *data parameter of the XML parser instead of using a global variable.

@fangfufu fangfufu May 15, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@svfrd , I am just having a quick look. I am not sure if this is relevant. I will need to have a closer look. But if you think it is not relevant, do let me know.

Comment thread src/sonic.c Outdated
@fangfufu

fangfufu commented May 15, 2026

Copy link
Copy Markdown
Owner

@svfrd, could you address the review comments that the bots flagged up please? Feel free to ignore that stuff that you think are irrelevant. Let me know when this is ready for a proper round of review.

There is a pre-commit failure that needs to be fixed too.

Let's try and get this merged over the weekend, or by the end of next week.

Comment thread src/link.c Outdated
* it instead of unconditionally calling the constructor.
*
* Without this, every fs_readdir() on /A would call
* sonic_LinkTable_new_id3(letter_A->sonic.depth // 0

@fangfufu fangfufu May 15, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the SonarCloud style suggestion.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread src/sonic.c Outdated
@fangfufu

Copy link
Copy Markdown
Owner

Please update the changelog too.

@fangfufu

Copy link
Copy Markdown
Owner

@svfrd , can you please follow the guideline here and install pre-commit? It is still not passing the pre-commit workflow.

https://github.com/fangfufu/httpdirfs/blob/master/src/README.md

Comment thread src/link.c
fangfufu added 3 commits May 16, 2026 01:43
When a Link already has a populated next_table, reuse it instead of
unconditionally re-creating it. This prevents memory leaks and
unnecessary I/O.
Track the current <index> element explicitly in the Subsonic ID3 XML
parser using an end-element handler. This replaces the previous
heuristic of using the last link added to the root, which could mis-parent
artists if an <index> produced no link or if elements arrived in an
unexpected order.
@sonarqubecloud

Copy link
Copy Markdown

Comment thread src/link.c
@fangfufu
fangfufu merged commit a2f517c into fangfufu:master May 16, 2026
10 checks passed
@fangfufu

Copy link
Copy Markdown
Owner

@svfrd, this is a fairly major bug fix. Thank you for helping out.

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.

2 participants