In GS 10.02.0RC1 the operation "0 copy" leads to a stackunderflow error if the operand stack is empty. I guess this isn't a new intended behavior. GS>0 copy Error: /stackunderflow in --copy-- Operand stack: 0 Execution stack: %interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- %loop_continue --nostringval-- --nostringval-- false 1 %stopped_push .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- Dictionary stack: --dict:750/1123(ro)(G)-- --dict:0/20(G)-- --dict:85/200(L)-- Current allocation mode is local Last OS error: No such file or directoryCurrent file position is 7 GS<1>
Looks like correct behaviour to me, going by the PLRM. There should always be at least 2 operands to the copy operator and stackunderflow is both permitted and reasonable. copy any1 … anyn n copy any1 … anyn any1 … anyn array1 array2 copy subarray2 dict1 dict2 copy dict2 string1 string2 copy substring2 packedarray1 array2 copy subarray2 gstate1 gstate2 copy gstate2 This is probably a result of much recent work relating to 'security' problems which has involved a lot of checking of operands and stack status. If previous behaviour differed I'd expect that to have been incorrect. But I'm willing to be convinced otherwise if you can point to evidence that current behaviour is incorrect.
Thank you for the fast reply and the helpful information. I can't find any details about the correct behavior of "clear 0 copy". PLRM only mentions that n must be a non-negative integer, but how to interpret operand sequence any_1 ... any_n if n=0 is not further specified. In my opinion, both the former and the new implementation are therefore valid interpretations. Is it really a necessary security enhancement if "0 copy" requires an additional (dummy) operand instead of just doing nothing? From a user perspective it's not hard to work around the new incompatibility but at the moment I can't see any advantages in changing the former behavior.
Two other PS interpreters concur that "0 copy" is valid.
Support of unreasonable edge cases is needed to make the code simple and reliable. For instance: /double_the_stack {count copy} def
(In reply to Martin Gieseking from comment #2) > Is it really a necessary security enhancement if "0 copy" requires an > additional (dummy) operand instead of just doing nothing? From a user > perspective it's not hard to work around the new incompatibility but at the > moment I can't see any advantages in changing the former behavior. No I realised what you were driving at a couple of minutes after I turned my computer off, but at gone 7pm I didn't want to go back. I'll look into it this morning, though why you would want to do s no-op like this escapes me, such a program would obviously be inefficient.
(In reply to Ken Sharp from comment #5) > I'll look into it this morning, though why you would want to do s no-op like > this escapes me, such a program would obviously be inefficient. For my applications, I don't need it as a pure end in itself to do nothing but as a special case where a variable operand n can be 0, similar to Alex' example. With the new behavior, it's always necessary to check whether n is 0 and whether copy might fail due to an empty stack which breaks existing code and makes the use of copy more cumbersome. To me, the specification in PLRM just says that "copy" needs n+1 operands if the top element is a non-negative integer. If there are less than n+1 elements on the stack, it terminates with /stackunderflow. After popping n, it then duplicates the n topmost elements. In case of n=0, it just does nothing but also doesn't require further elements to operate on. Thus, I don't see the need to check for additional, unrelated elements on the stack. I also can't really read that as a hard requirement from the specification given in PLRM.
This commit 9e64c191228b4c026d50fc6e1e4fd5f80d2df881 restores the previous behaviour Thanks for testing the release candidate and taking the trouble to make a report!
Great! Thank you for having a look into this issue and for restoring the previous behavior.