Skip to content

Commit 506067b

Browse files
authored
fix: Fix a bug that could cause a crash when deleting a shared procedure definition. (#2560)
* Fix: Fix bug that could cause a crash when deletion a procedure definition. * chore: Add test to exercise the scenario.
1 parent f90172b commit 506067b

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed

plugins/block-shareable-procedures/src/blocks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ const procedureCallerUpdateShapeMixin = {
10661066
* Updates the shape of this block to reflect the state of the data model.
10671067
*/
10681068
doProcedureUpdate: function () {
1069-
if (!this.getProcedureModel()) return;
1069+
if (!this.getProcedureModel() || this.isDeadOrDying()) return;
10701070
const id = this.getProcedureModel().getId();
10711071
if (
10721072
!this.getTargetWorkspace_().getProcedureMap().has(id) &&

plugins/block-shareable-procedures/test/procedure_blocks.mocha.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,93 @@ suite('Procedures', function () {
13011301
},
13021302
);
13031303

1304+
test(
1305+
'when a procedure definition block is deleted, deleting its callers ' +
1306+
'with arguments that call another procedure does not cause a crash',
1307+
function () {
1308+
// This test exercises the scenario reported in
1309+
// https://github.com/google/blockly-samples/issues/2557
1310+
Blockly.serialization.workspaces.load(
1311+
{
1312+
blocks: {
1313+
languageVersion: 0,
1314+
blocks: [
1315+
{
1316+
type: 'procedures_defnoreturn',
1317+
id: 'dosomething',
1318+
extraState: {
1319+
procedureId: 'dosomething_procmodel',
1320+
},
1321+
fields: {
1322+
NAME: 'do something',
1323+
},
1324+
},
1325+
{
1326+
type: 'procedures_defreturn',
1327+
id: 'dosomething2',
1328+
extraState: {
1329+
procedureId: 'dosomething2_procmodel',
1330+
},
1331+
fields: {
1332+
NAME: 'do something2',
1333+
},
1334+
},
1335+
{
1336+
type: 'procedures_callnoreturn',
1337+
id: 'call_dosomething',
1338+
extraState: {
1339+
name: 'do something',
1340+
params: ['x'],
1341+
},
1342+
inputs: {
1343+
ARG0: {
1344+
block: {
1345+
type: 'procedures_callreturn',
1346+
id: 'call_dosomething2',
1347+
extraState: {
1348+
name: 'do something2',
1349+
},
1350+
},
1351+
},
1352+
},
1353+
},
1354+
],
1355+
},
1356+
variables: [
1357+
{
1358+
name: 'x',
1359+
id: 'x_var',
1360+
},
1361+
],
1362+
procedures: [
1363+
{
1364+
id: 'dosomething_procmodel',
1365+
name: 'do something',
1366+
returnTypes: null,
1367+
parameters: [
1368+
{
1369+
id: 'x_param',
1370+
name: 'x',
1371+
},
1372+
],
1373+
},
1374+
{
1375+
id: 'dosomething2_procmodel',
1376+
name: 'do something2',
1377+
returnTypes: [],
1378+
},
1379+
],
1380+
},
1381+
this.workspace,
1382+
);
1383+
1384+
const defBlock = this.workspace.getBlockById('dosomething');
1385+
// Should not cause an exception to be thrown.
1386+
defBlock.dispose();
1387+
globalThis.clock.runAll();
1388+
},
1389+
);
1390+
13041391
test(
13051392
'when a procedure definition block is deleted, a delete event for ' +
13061393
'its data model is fired',

0 commit comments

Comments
 (0)