Skip to content

fix(koptocr): crash bugs from assert-only checks and uninitialized variables - #67

Open
tachibana-shin wants to merge 6 commits into
koreader:masterfrom
tachibana-shin:fix/koptocr-issue
Open

fix(koptocr): crash bugs from assert-only checks and uninitialized variables#67
tachibana-shin wants to merge 6 commits into
koreader:masterfrom
tachibana-shin:fix/koptocr-issue

Conversation

@tachibana-shin

@tachibana-shin tachibana-shin commented Jul 22, 2026

Copy link
Copy Markdown
  • Replace assert() with runtime checks — asserts are compiled out in release builds, leaving bounds and bpp validation as no-ops
  • Add early return for invalid box_type — uninitialized pboxa/pnai pointers were dereferenced
  • Remove static from local variables — re-initialized every call, static prevents proper init and is not thread-safe
  • Add input validation in bitmap2pix() — null/bounds checks before memory access

This change is Reviewable

assert() is compiled out in release builds (NDEBUG), making bounds
checks and bpp validation no-ops in production. Replace with proper
runtime checks that work in all build configurations.
If box_type is neither 0 nor 1, pboxa and pnai remain uninitialized,
leading to undefined behavior when dereferenced. Add else branch to
return early on invalid input.
_k2settings and initstr are re-initialized on every call via
k2pdfopt_settings_init_from_koptcontext() and
k2pdfopt_settings_new_source_document_init(). The static qualifier
provides no benefit, prevents proper re-initialization, and is not
thread-safe.
Validate src pointer, data pointer, coordinates and dimensions before
accessing bitmap memory. Returns NULL on invalid input instead of
causing out-of-bounds reads.
Comment thread lib/koptocr.c
if (*pboxa == NULL && *pnai == NULL && src->bpp) {
assert(x + w <= src->width);
assert(y + h <= src->height);
if (x < 0 || y < 0 || x + w > src->width || y + h > src->height)

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.

Should it do both?

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.

To clarify, the way I see it assert() is so you know immediately during development, while silently swallowing or working around any issues is generally the preferred behavior for a release build. The checks may be very similar but the purpose behind them is different. So I'd add rather than replace.

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.

Personally, I don't like using assert in these places at all, but I'll add them back in

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 also want to keep any diffs as minimal as possible because these are custom patches on top of a code base. ;-)

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.

Pardon, this is our file. Either way, I like hard fails. Silently swallowing them means I don't know about it.

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.

Yes, please! I have some changes I need to PR, disabling dead code (among other things), maybe hold off further PRs until those have been merged, @tachibana-shin, no sense in duplicating work or fixing stuff we don't use.

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.

Yes, please! I have some changes I need to PR, disabling dead code (among other things), maybe hold off further PRs until those have been merged, @tachibana-shin, no sense in duplicating work or fixing stuff we don't use.

Great, I'm having a lot of trouble with some issues that I later discovered Koreader never even mentions.

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.

Pardon, this is our file. Either way, I like hard fails. Silently swallowing them means I don't know about it.

I've re-added the asserts here, but what about below—do you think we should re-add them there too? If we do, it would look something like this:

} else {
asserts(false);
}

Add assertions to validate dimensions before processing.
Comment thread lib/koptocr.c
}
} else {
assert(src->bpp == 24);
} else if (src->bpp == 24) {

@tachibana-shin tachibana-shin Jul 22, 2026

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.

@Frenzie Do I need to add an assert here? It would look like this: } else { assert(false); }

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.

Looks like @benoit-pierre added that assert (not at my request) so I'll hand off that question.

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.

3 participants