Skip to content

viewer: fix crash when viewing files with PK/ZIP magic bytes#5058

Open
ilia-maslakov wants to merge 3 commits intoMidnightCommander:masterfrom
ilia-maslakov:fix-viewer-zip-crash
Open

viewer: fix crash when viewing files with PK/ZIP magic bytes#5058
ilia-maslakov wants to merge 3 commits intoMidnightCommander:masterfrom
ilia-maslakov:fix-viewer-zip-crash

Conversation

@ilia-maslakov
Copy link
Copy Markdown

@ilia-maslakov ilia-maslakov commented Mar 9, 2026

Summary

  • Fix segfault when pressing F3 on files with PK/ZIP magic bytes (PPTX, DOCX, ODS, ODT, JAR, etc.)
  • When VFS decompression fails, silently display raw file content instead of corrupting viewer state

Root cause

In mcview_load(), when get_compression_type() detects a ZIP header and mc_open() on the VFS decompression path fails (fd1 == -1):

  1. mcview_close_datasource(view) is called but datasource is DS_NONE (no-op)
  2. mcview_show_error() for in-panel viewers calls mcview_set_datasource_string(), setting datasource to DS_STRING
  3. No goto/return, so execution falls through to mcview_set_datasource_file() which overwrites datasource to DS_FILE without cleaning up DS_STRING state

Sample content of the test file

The following hex content produces a file that causes mcview to segfault when opened:

50 4B 03 04 14 00 00 00 08 00

This corrupts viewer state and causes segfault on subsequent F3.

Test plan

  • Create a file without extention containing the hex content above.
  • Open this file in mcview
  • F3 - should show raw file content without error dialog
  • Close viewer, press F3 again - no crash

@github-actions github-actions bot added this to the Future Releases milestone Mar 9, 2026
@github-actions github-actions bot added needs triage Needs triage by maintainers prio: medium Has the potential to affect progress labels Mar 9, 2026
@mc-worker
Copy link
Copy Markdown
Contributor

/rebase

@mc-butler mc-butler force-pushed the fix-viewer-zip-crash branch from 6221ecb to 74c9f0c Compare April 5, 2026 10:49
@mc-worker mc-worker added area: mcview mcview, the built-in text editor and removed needs triage Needs triage by maintainers labels Apr 5, 2026
@mc-worker mc-worker self-requested a review April 5, 2026 11:13
@mc-worker
Copy link
Copy Markdown
Contributor

@ilia-maslakov I've cleaned up your test and created a fix-viewer-zip-crash branch in this repo. If you are agree with my changes, please take them.

@mc-worker mc-worker requested a review from zyv April 5, 2026 11:23
@zyv
Copy link
Copy Markdown
Member

zyv commented Apr 5, 2026

I've cleaned up your test and created a fix-viewer-zip-crash branch in this repo. If you agree with my changes, please take them.

I vaguely remember we had a related problem some time ago:

What I'm not sure about is what the right way to behave here is. I think the idea before was to show an error message. Now the file is silently opened in the raw mode. Is this desired @mc-worker ? Do you know if this is consistent with other viewer behaviors?

void mc_editor_plugins_load (void) {}
int button_get_width (void *b) { (void) b; return 0; }

#pragma GCC diagnostic pop
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this should be handled as it is done here: b6012a2 .

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

ok

Comment on lines +67 to +70
mcview_compute_areas (WView *view)
{
(void) view;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
mcview_compute_areas (WView *view)
{
(void) view;
}
mcview_compute_areas (MC_UNUSED WView *view)
{
}

Comment on lines +151 to +152
ssize_t written = write (fd, data, size);
(void) written;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
ssize_t written = write (fd, data, size);
(void) written;
write (fd, data, size);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

fixed

@ilia-maslakov
Copy link
Copy Markdown
Author

I've cleaned up your test and created a fix-viewer-zip-crash branch in this repo. If you agree with my changes, please take them.

I vaguely remember we had a related problem some time ago:

* [mcview does not open for empty archives (xz, zstd, etc.) #4741](https://github.com/MidnightCommander/mc/issues/4741)

What I'm not sure about is what the right way to behave here is. I think the idea before was to show an error message. Now the file is silently opened in the raw mode. Is this desired @mc-worker ? Do you know if this is consistent with other viewer behaviors?

It’s better to open the file in raw mode and show at least some result (even if it’s empty) than to interrupt the user with a pop-up error message. This makes the behavior more predictable and less annoying.

When mcview opens a file with PK/ZIP magic bytes (e.g. PPTX, DOCX, ODS,
ODT, JAR), get_compression_type() detects COMPRESSION_ZIP and attempts
VFS decompression. If mc_open() on the VFS path fails (fd1 == -1):

1. mcview_close_datasource(view) is called but datasource is DS_NONE (no-op)
2. mcview_show_error() for in-panel viewers calls mcview_set_datasource_string(),
   setting datasource to DS_STRING
3. No goto/return, so execution falls through to mcview_set_datasource_file()
   which overwrites datasource to DS_FILE without cleaning up DS_STRING state

This corrupts viewer state and causes segfault on subsequent F3 invocation.

Fix: when VFS decompression fails, silently fall through to display raw
file content. The file is valid and readable, there is no reason to show
an error.

Closes: MidnightCommander#4760

Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
Add tests verifying that mcview_load correctly handles files with
PK/ZIP magic bytes (PPTX, DOCX, ODS, JAR, etc.) when VFS decompression
fails. Tests cover:
- ZIP-magic file loads as DS_FILE without error
- repeated load does not crash (regression for second-F3 segfault)
- normal text file loads correctly
- nonexistent file returns FALSE
- gzip-magic file also loads without error

Mark viewer display/lib functions and file_error_message, message,
load_file_position as MC_MOCKABLE to enable test overrides.

Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
Add extern forward declarations for global linker stub variables
(mc_skin_color__cache, mc_editor_plugin_list, we_are_strstrstrbackground)
to satisfy -Wmissing-variable-declarations. These variables must remain
non-static as they are referenced by name from libinternal.a objects.

Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
@ossilator
Copy link
Copy Markdown
Contributor

This makes the behavior more predictable and less annoying.

most definitely NOT. you can't seriously argue that silently doing something different than expected is predictable.

if you want to avoid the disruptiveness of a message box, put a red banner above the scrollable area. but then some other mechanism to dismiss the message is required - i guess manually switching to raw mode would do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: mcview mcview, the built-in text editor prio: medium Has the potential to affect progress

Development

Successfully merging this pull request may close these issues.

Cannot open <OpenDocument file path> in parse mode. Operation not supported (95)

4 participants