-
Jon Olav Hauglid authored
The problem was that if a stored routine had nested continue handlers in more than two separate scopes, we could end up continuing from the wrong instruction after handler exit. The stored routine structure had to be something like this: BEGIN <continue handler 3> <contine handler 4> BEGIN <continue handler 1> <continue handler 2> END END The bug would occur if we ended up activating handler 1, and handler 1 caused activation of handler 2, handler 2 caused activation of handler 3 and handler 3 caused activation of handler 4. Since all these are continue handlers, each handler should return to the instruction after the instruction that raised the condition triggering the handler. However, we ended up continuing with the wrong instruction. Internally we maintain a stack of handler activations. When a handler exits, we pop the top element off this stack. But we also check if more handlers need to be popped off the stack, in case when more handlers are defined for the scope we are leaving. To determine this we check scope level which is 0 for the outermost scope and 1, 2, ... for inner scopes. In the example above, the stack will be: <continue handler 4> - scope level 3 <continue handler 3> - scope level 1 <continue handler 2> - scope level 4 <continue handler 1> - scope level 2 When exiting <continue handler 4>, we first popped it from the stack. We then checked if other handlers with scope level > 3 existed. Since <continue handler 2> was found, we popped again. This is wrong for two reasons: 1) <continue handler 2> belongs to a separate scope, not the scope we are leaving. 2) By popping, we always removed the top element - in this case <continue handler 3>, not <continue handler 2> which we checked. This patch fixes the problem by only popping from the stack until we find the first handler which is still appropriate. This prevents popping of handlers which, while having a higher scope level, belongs to a separate nested scope.
Jon Olav Hauglid authoredThe problem was that if a stored routine had nested continue handlers in more than two separate scopes, we could end up continuing from the wrong instruction after handler exit. The stored routine structure had to be something like this: BEGIN <continue handler 3> <contine handler 4> BEGIN <continue handler 1> <continue handler 2> END END The bug would occur if we ended up activating handler 1, and handler 1 caused activation of handler 2, handler 2 caused activation of handler 3 and handler 3 caused activation of handler 4. Since all these are continue handlers, each handler should return to the instruction after the instruction that raised the condition triggering the handler. However, we ended up continuing with the wrong instruction. Internally we maintain a stack of handler activations. When a handler exits, we pop the top element off this stack. But we also check if more handlers need to be popped off the stack, in case when more handlers are defined for the scope we are leaving. To determine this we check scope level which is 0 for the outermost scope and 1, 2, ... for inner scopes. In the example above, the stack will be: <continue handler 4> - scope level 3 <continue handler 3> - scope level 1 <continue handler 2> - scope level 4 <continue handler 1> - scope level 2 When exiting <continue handler 4>, we first popped it from the stack. We then checked if other handlers with scope level > 3 existed. Since <continue handler 2> was found, we popped again. This is wrong for two reasons: 1) <continue handler 2> belongs to a separate scope, not the scope we are leaving. 2) By popping, we always removed the top element - in this case <continue handler 3>, not <continue handler 2> which we checked. This patch fixes the problem by only popping from the stack until we find the first handler which is still appropriate. This prevents popping of handlers which, while having a higher scope level, belongs to a separate nested scope.
Loading