Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: decode media names before inserting into the database #18019

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Sahil06012002
Copy link
Contributor

@Sahil06012002 Sahil06012002 commented Feb 25, 2025

Issue:

Check Media shows incorrect values when media filenames contain special characters (spaces, %, &, =, etc.) on Android, while the desktop version works as expected.

Cause:

According to the [Anki manual](https://docs.ankiweb.net/media.html#media), filenames with spaces or special characters appear differently in the HTML editor compared to how they are stored on disk. For example, hello 100%.jpg is displayed as hello%20100%25.jpg in the editor.

HTML encoding is likely applied because certain characters have special meanings in URLs and HTML syntax. Without proper encoding, the card rendering engine may fail to locate or display media files with special characters in their names.

For instance, if a file named test,.jpg is referenced in a card, it gets encoded as test%2C.jpg in the editor for proper rendering, while the actual file on disk remains test,.jpg.

Observations:

  • When adding a card using the desktop version, the original filename is stored in the collection.anki2 database (notes table).
  • When adding media via Android, the filename is stored in an encoded format.
    Scrrenshot of the notes table :
synv_ev

This discrepancy causes the check_media function to return incorrect results for media files added from Android when their names include special characters.

Approach

Now, while adding card in a deck addNote() function is called
https://github.com/Sahil06012002/Anki-Android/blob/fb3eec394463e19f0b3db3fdaa5b6b1eb156879a/AnkiDroid/src/main/java/com/ichi2/anki/NoteEditor.kt#L1198
that stores the note in the database.

Decoding the media filenames before storing them in the database resolves the issue.
Before calling addNote(editorNote!!, deckId), the fields parameter in editorNote is updated to replace encoded filenames with their decoded versions :
https://github.com/Sahil06012002/Anki-Android/blob/fb3eec394463e19f0b3db3fdaa5b6b1eb156879a/AnkiDroid/src/main/java/com/ichi2/anki/NoteEditor.kt#L2579 .

Fixes

How Has This Been Tested?

Checklist

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code
  • UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)
  • UI Changes: You have tested your change using the Google Accessibility Scanner

Copy link
Member

@BrayanDSO BrayanDSO left a comment

Choose a reason for hiding this comment

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

A description of the issue and how this fix it would be appreciated. You also said that you had thought about other ways to fix it. What are they?

@@ -2575,7 +2575,8 @@ class NoteEditor :

private fun updateField(field: FieldEditText?): Boolean {
val fieldContent = field!!.text?.toString() ?: ""
val correctedFieldContent = NoteService.convertToHtmlNewline(fieldContent, shouldReplaceNewlines())
// Decode the file name when preparing data for saveNote() to handle special characters correctly
Copy link
Member

Choose a reason for hiding this comment

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

the // should follow the surrounding indent

@@ -2575,7 +2575,8 @@ class NoteEditor :

private fun updateField(field: FieldEditText?): Boolean {
val fieldContent = field!!.text?.toString() ?: ""
val correctedFieldContent = NoteService.convertToHtmlNewline(fieldContent, shouldReplaceNewlines())
// Decode the file name when preparing data for saveNote() to handle special characters correctly
val correctedFieldContent = Uri.decode(NoteService.convertToHtmlNewline(fieldContent, shouldReplaceNewlines()))
Copy link
Member

Choose a reason for hiding this comment

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

Won't this affect any kind of encoded content the user has added?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not aware of any instances where users would intentionally add encoded content, but this is something to consider. If necessary, we might need to ensure that only media filenames are decoded rather than applying decoding to all fields.

Do you know of any cases where users might intentionally add encoded content?

Copy link
Member

Choose a reason for hiding this comment

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

From memory, no. But in Anki there are always someone doing stuff like that

@BrayanDSO BrayanDSO added the Needs Author Reply Waiting for a reply from the original author label Feb 28, 2025
@Sahil06012002
Copy link
Contributor Author

A description of the issue and how this fix it would be appreciated. You also said that you had thought about other ways to fix it. What are they?

I have updated the PR description for better clarity.

Regarding the second question, modifying the editorNote parameter anywhere before passing it to addNote() would effectively resolve the issue. Initially, I tried to fix it by updating the fields parameter in NoteEditor.kt at

as follows:

editorNote!!.fields.replaceAll { Uri.decode(it) }
addNote(editorNote!!, deckId)

But, this introduces an extra iteration, which is unnecessary. If needed, we can update editorNote at any suitable point before calling addNote() to optimize the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Author Reply Waiting for a reply from the original author
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Check Media Deletes Used Files
2 participants