# Extended 4.4 — B2DPlugin: divide-by-zero on Form depth == 0

Bug ref      : pharo.md §4.4 (also covered for BitBlt by extended 3.5)
Severity     : HIGH (SIGFPE in the B2D bitmap-fill path)
File         : extracted/plugins/B2DPlugin/src/common/B2DPlugin.c
Lines (HEAD) : ~9672 (bitmap-fill allocate path)

## Problem

```c
ppw = 32 / bmDepth;          // crash if bmDepth == 0
bmRaster = (bmWidth + (ppw - 1)) / ppw;
if (!(bmBitsSize == (bmRaster * bmHeight))) ...
```

`bmDepth` is read from the Form with no `!= 0` check.

## Fix

Same defensive depth-set check as in extended/3.5 for BitBlt.

```diff
diff --git a/plugins/B2DPlugin/src/common/B2DPlugin.c b/plugins/B2DPlugin/src/common/B2DPlugin.c
index 9cafd4318..c9a5641df 100644
--- a/plugins/B2DPlugin/src/common/B2DPlugin.c
+++ b/plugins/B2DPlugin/src/common/B2DPlugin.c
@@ -9669,12 +9669,23 @@ primitiveAddBitmapFill(void)
 		fill = primitiveFail();
 		goto l14;
 	}
-	ppw = 32 / bmDepth;
-	bmRaster = (bmWidth + (ppw - 1)) / ppw;
-	if (!(bmBitsSize == (bmRaster * bmHeight))) {
+	/* Restrict depth to values BitBlt/B2D actually support; any other
+	 * value would trip a divide-by-zero in `32 / bmDepth` below. */
+	if (!(bmDepth == 1 || bmDepth == 2 || bmDepth == 4 ||
+	      bmDepth == 8 || bmDepth == 16 || bmDepth == 32)) {
 		fill = primitiveFail();
 		goto l14;
 	}
+	ppw = 32 / bmDepth;
+	bmRaster = (bmWidth + (ppw - 1)) / ppw;
+	{
+		/* uint64 to avoid signed overflow on the multiply. */
+		uint64_t required = (uint64_t)bmRaster * (uint64_t)bmHeight;
+		if ((uint64_t)bmBitsSize != required) {
+			fill = primitiveFail();
+			goto l14;
+		}
+	}
 	/* begin allocateBitmapFill:colormap: */
 	fillSize = GBMBaseSize + cmSize;
 	if (!(allocateObjEntry(fillSize))) {

```

## Test plan

- B2D bitmap-fill with a Form of depth 0: before, SIGFPE; after,
  clean primitive fail.
- Normal fills (depth 8/16/32): unchanged.

## Risk notes

- Mirrors extended/3.5; both should land together for full coverage
  of the depth=0 vector.
