Index: uspace/app/bithenge/transform.c
===================================================================
--- uspace/app/bithenge/transform.c	(revision f85ca3f2b6b9dbdcf2a617bcc94811a77ad88b97)
+++ uspace/app/bithenge/transform.c	(revision 84e8a70fb5dac69e0b565be78ea41d316afc452c)
@@ -387,4 +387,5 @@
 	bithenge_scope_t scope;
 	bithenge_blob_t *blob;
+	bool prefix;
 } struct_node_t;
 
@@ -497,11 +498,13 @@
 	}
 
-	aoff64_t remaining;
-	rc = bithenge_blob_size(blob, &remaining);
-	if (rc != EOK)
-		goto error;
-	if (remaining != 0) {
-		rc = EINVAL;
-		goto error;
+	if (!struct_node->prefix) {
+		aoff64_t remaining;
+		rc = bithenge_blob_size(blob, &remaining);
+		if (rc != EOK)
+			goto error;
+		if (remaining != 0) {
+			rc = EINVAL;
+			goto error;
+		}
 	}
 
@@ -514,7 +517,12 @@
 {
 	struct_node_t *node = node_as_struct(base);
+
+	/* We didn't inc_ref for the scope in struct_transform_make_node, so
+	 * make sure it doesn't try to dec_ref. */
+	node->scope.current_node = NULL;
+	bithenge_scope_destroy(&node->scope);
+
 	bithenge_transform_dec_ref(struct_as_transform(node->transform));
 	bithenge_blob_dec_ref(node->blob);
-	bithenge_scope_destroy(&node->scope);
 	free(node);
 }
@@ -525,10 +533,8 @@
 };
 
-static int struct_transform_apply(bithenge_transform_t *base,
-    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
-{
-	struct_transform_t *self = transform_as_struct(base);
-	if (bithenge_node_type(in) != BITHENGE_NODE_BLOB)
-		return EINVAL;
+static int struct_transform_make_node(struct_transform_t *self,
+    bithenge_node_t **out, bithenge_scope_t *scope, bithenge_blob_t *blob,
+    bool prefix)
+{
 	struct_node_t *node = malloc(sizeof(*node));
 	if (!node)
@@ -547,12 +553,28 @@
 		return rc;
 	}
-	bithenge_transform_inc_ref(base);
+	bithenge_transform_inc_ref(struct_as_transform(self));
+	bithenge_blob_inc_ref(blob);
 	node->transform = self;
-	bithenge_node_inc_ref(in);
-	node->blob = bithenge_node_as_blob(in);
+	node->blob = blob;
+	node->prefix = prefix;
 	*out = struct_as_node(node);
-	bithenge_node_inc_ref(*out);
+
+	/* We should inc_ref(*out) here, but that would make a cycle. Instead,
+	 * we leave it 1 too low, so that when the only remaining use of *out
+	 * is the scope, *out will be destroyed. Also see the comment in
+	 * struct_node_destroy. */
 	bithenge_scope_set_current_node(&node->scope, *out);
-	return EOK;
+
+	return EOK;
+}
+
+static int struct_transform_apply(bithenge_transform_t *base,
+    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
+{
+	struct_transform_t *self = transform_as_struct(base);
+	if (bithenge_node_type(in) != BITHENGE_NODE_BLOB)
+		return EINVAL;
+	return struct_transform_make_node(self, out, scope,
+	    bithenge_node_as_blob(in), false);
 }
 
@@ -561,5 +583,11 @@
 {
 	struct_transform_t *self = transform_as_struct(base);
-	int rc = EOK;
+	bithenge_node_t *struct_node;
+	int rc = struct_transform_make_node(self, &struct_node, scope, blob,
+	    true);
+	if (rc != EOK)
+		return rc;
+	bithenge_scope_t *inner = &node_as_struct(struct_node)->scope;
+
 	bithenge_node_t *node;
 	bithenge_blob_inc_ref(blob);
@@ -574,5 +602,5 @@
 		    self->subtransforms[i].transform;
 		aoff64_t sub_size;
-		rc = bithenge_transform_prefix_length(subxform, scope, blob,
+		rc = bithenge_transform_prefix_length(subxform, inner, blob,
 		    &sub_size);
 		if (rc != EOK)
@@ -585,7 +613,9 @@
 		blob = bithenge_node_as_blob(node);
 	}
+
 error:
+	bithenge_node_dec_ref(struct_node);
 	bithenge_blob_dec_ref(blob);
-	return EOK;
+	return rc;
 }
 
Index: uspace/dist/src/bithenge/test.bh
===================================================================
--- uspace/dist/src/bithenge/test.bh	(revision 84e8a70fb5dac69e0b565be78ea41d316afc452c)
+++ uspace/dist/src/bithenge/test.bh	(revision 84e8a70fb5dac69e0b565be78ea41d316afc452c)
@@ -0,0 +1,13 @@
+transform pascal_string = struct {
+	.len <- uint8;
+	.string <- ascii <- known_length(.len);
+};
+
+transform item(first_len, second_len) = struct {
+	.id <- uint32le <- known_length(4); # the known_length is unnecessary
+	.name <- pascal_string;
+	.first <- known_length(first_len);
+	.second <- known_length(second_len);
+};
+
+transform main() = item(3, 0);
