Skip to content

Normalize zero block_z in validate_config to avoid divide by zero - #678

Merged
solidpixel merged 3 commits into
ARM-software:mainfrom
17krishna8:fix-block-z-zero
Oct 21, 2026
Merged

solidpixel merged 3 commits into
ARM-software:mainfrom
17krishna8:fix-block-z-zero

Conversation

@17krishna8

Copy link
Copy Markdown
Contributor

Description

astcenc_context_alloc() accepts a hand-built astcenc_config in addition to one populated by astcenc_config_init(). validate_block_size() treats a block_z of zero as meaning "2D", the same as a value of one, and astcenc_config_init() normalizes its own block_z input to at least one before storing it (astcenc_entry.cpp line 527). However validate_config() did not apply the same normalization to the copy of the config stored in the context, so a context can be created holding block_z == 0.

The stored block dimensions are later used as divisors when computing block counts:

// astcenc_compress_image() / astcenc_decompress_image()
size_t blocks_z = astc::get_block_count_safe(dim_z, block_z);

A config with block_z set to zero therefore causes a division by zero (SIGFPE) in get_block_count_safe() on the first encode or decode call, instead of behaving like the equivalent 2D config with block_z == 1.

Reproducer

astcenc_config config;
astcenc_config_init(ASTCENC_PRF_LDR, 6, 6, 1, ASTCENC_PRE_FASTEST, 0, &config);
config.block_z = 0;                       // treat zero as "2D"

astcenc_context* ctx;
astcenc_context_alloc(&config, 1, &ctx, nullptr);   // accepted

astcenc_decompress_image(ctx, ...);        // SIGFPE: dim_z / block_z

Changes

  • Normalize the stored block_z to at least one in validate_config(), which runs on every astcenc_context_alloc() call, matching the normalization astcenc_config_init() already applies to its own inputs.
  • Add a unit test covering a config with block_z == 0 (fails with a divide-by-zero or a wrong context config on the old code, passes after the fix).

Behavior is otherwise unchanged for any config built through astcenc_config_init(), which already normalizes block_z to at least one.

17krishna8 and others added 3 commits October 20, 2026 15:13
astcenc_context_alloc() accepts a hand-built astcenc_config, and
validate_block_size() treats a block_z of zero as meaning a 2D block
size, the same as a value of one. astcenc_config_init() normalizes its
own block_z input to at least one, but validate_config() did not apply
the same normalization to the copy stored in the context.

The stored block dimensions are later used as divisors by
astcenc_compress_image() and astcenc_decompress_image() when computing
block counts, so a config with block_z set to zero causes a division by
zero (SIGFPE) in get_block_count_safe() on the first encode or decode
call, instead of returning a normal error code.

Normalize the stored value to at least one in validate_config(), which
runs on every context allocation, so the context can never be created
with a zero block divisor.
@solidpixel
solidpixel merged commit 72fee71 into ARM-software:main Oct 21, 2026
17 checks passed
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