diff --git a/src/maxicode.ps.src b/src/maxicode.ps.src index 180aa9d6..ea65d338 100644 --- a/src/maxicode.ps.src +++ b/src/maxicode.ps.src @@ -97,20 +97,22 @@ begin % Special message handling for modes 2 and 3 mode 2 eq mode 3 eq or { - % Convert to a string for extracting the structured data + % Convert to a string (up to first ECI) for extracting the structured data /barcode msglen string def + /barlen msglen def 0 1 msglen 1 sub { /i exch def - msg i get 0 gt { - barcode i msg i get put - } if + msg i get 0 lt {/barlen i def exit} if + barcode i msg i get put } for - /barlen barcode length def + /difflen msglen barlen sub def % Normalise messages that begin with a field identifier [)>{RS}01{GS}yy /fid () def - barlen 7 ge { - barcode 0 7 getinterval <5b293e1e30311d> eq { + barlen 9 ge { + barcode dup 0 7 getinterval <5b293e1e30311d> eq + exch dup 7 get dup 48 ge exch 57 le and + exch 8 get dup 48 ge exch 57 le and and and { /fid barcode 0 9 getinterval def /barcode barcode 9 barlen 9 sub getinterval def } if @@ -123,21 +125,26 @@ begin mode 2 eq { true 1 { - pcode length 9 gt { pop false exit } if + pcode length dup 9 gt exch 0 eq or { pop false exit } if pcode { dup 48 lt exch 57 gt or { pop false exit } if } forall } repeat not { - pop /bwipp.maxicodeBadMode2PostCode (A mode 2 postcode must not exceed 9 digits) //raiseerror exec + pop /bwipp.maxicodeBadMode2PostCode (A mode 2 postcode must not be empty or exceed 9 digits) //raiseerror exec } if } { % mode=3 - pcode { - dup 32 eq % SP - exch dup dup 34 ge exch 58 le and % punct, 0-9, : - exch dup 65 ge exch 90 le and % A-Z - or or not { - pop /bwipp.maxicodeBadMode3PostCode (A mode 3 postcode must not exceed 6 characters) //raiseerror exec - } if - } forall + true + 1 { + pcode length dup 6 gt exch 0 eq or { pop false exit } if + pcode { + dup 32 eq % SP + exch dup dup 34 ge exch 58 le and % punct, 0-9, : + exch dup 65 ge exch 90 le and % A-Z + or or not { pop false exit } if + } forall + } repeat + not { + pop /bwipp.maxicodeBadMode3PostCode (A mode 3 postcode must not be empty or exceed 6 characters) //raiseerror exec + } if } ifelse } { pop /bwipp.maxicodeExpectedPostCode (Expected postcode followed by group separator character) //raiseerror exec @@ -177,7 +184,7 @@ begin /barcode exch def /barlen barcode length def - /msg [ barcode {} forall ] def + /msg [ barcode {} forall msg msglen difflen sub difflen getinterval aload pop ] def /msglen msg length def } if diff --git a/tests/ps_tests/maxicode.ps.test b/tests/ps_tests/maxicode.ps.test index d2f1e91e..e6ac9195 100644 --- a/tests/ps_tests/maxicode.ps.test +++ b/tests/ps_tests/maxicode.ps.test @@ -16,6 +16,13 @@ isEqual } def +/er_tmpl { + 3 1 roll { 0 0 maxicode /pixs get } + dup 3 -1 roll 1 exch put + dup 3 -1 roll 0 exch put + exch isError +} def + % Zero-pad US postcodes that lack "+4" (Annex B.1.4a) /uszeropad % Expected codewords @@ -133,6 +140,43 @@ 28 28 28 28 28 28 28 28 26 26 45 45 49 49 38 38 31 31 5 5 44 44 43 43 7 7 12 12 1 1 62 62 58 58 43 43 57 57 13 13 31 31 29 29 53 53 45 45] debugIsEqual +{ % Exit SCM loop on first ECI and add remaining back later to avoid ECIs being replaced with NUL + ([^041>^03001^02996999999999^029840^029333^029^ECI000003A) + (mode=2 parse parsefnc debugcws newencoder) maxicode +} [50 63 9 43 57 30 2 18 55 20 47 30 3 41 62 27 45 42 6 32 59 42 41 59 40 30 48 49 29 57 54 27 + 3 1 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 + 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 + 33 33 33 33 33 33 33 33 59 62 7 62 19 52 10 28 8 60 12 40 47 51 37 47 29 49 19 46 47 52 56 44 + 32 51 45 42 40 49 14 32 37 2 16 26 1 6 51 37] debugIsEqual + +% Too short field identifier [)>{RS}01{GS}y (was causing rangecheck) +([^041>^03001^0299) (mode=2 parse dontdraw) /bwipp.maxicodeBadMode2PostCode er_tmpl + +% Field identifier with non-numeric yy (will be ignored and parsed as post code) +([^041>^03001^0299A) (mode=2 parse dontdraw) /bwipp.maxicodeBadMode2PostCode er_tmpl + +% Exercise the error checks +() (mode=2 dontdraw) /bwipp.maxicodeEmptyData er_tmpl +(A) (mode=1 dontdraw) /bwipp.maxicodeBadMode er_tmpl +(A) (mode=4 sam=11 dontdraw) /bwipp.maxicodeBadSAM er_tmpl +(A) (mode=4 sam=32 dontdraw) /bwipp.maxicodeBadSAM er_tmpl +(123456789) (mode=2 dontdraw) /bwipp.maxicodeExpectedPostCode er_tmpl +(^029) (mode=2 parse dontdraw) /bwipp.maxicodeBadMode2PostCode er_tmpl +(^029) (mode=3 parse dontdraw) /bwipp.maxicodeBadMode3PostCode er_tmpl +(1234567890^029) (mode=2 parse dontdraw) /bwipp.maxicodeBadMode2PostCode er_tmpl +(12345678A^029) (mode=2 parse dontdraw) /bwipp.maxicodeBadMode2PostCode er_tmpl +(ABCDEFG^029) (mode=3 parse dontdraw) /bwipp.maxicodeBadMode3PostCode er_tmpl +(ABCDEa^029) (mode=3 parse dontdraw) /bwipp.maxicodeBadMode3PostCode er_tmpl +(123456789^029) (mode=2 parse dontdraw) /bwipp.maxicodeExpectedCountryCode er_tmpl +(ABCDEF^029) (mode=3 parse dontdraw) /bwipp.maxicodeExpectedCountryCode er_tmpl +(123456789^029^029) (mode=2 parse dontdraw) /bwipp.maxicodeBadCountryCode er_tmpl +(123456789^02984^029) (mode=2 parse dontdraw) /bwipp.maxicodeBadCountryCode er_tmpl +(123456789^02984A^029) (mode=2 parse dontdraw) /bwipp.maxicodeBadCountryCode er_tmpl +(123456789^029840^029) (mode=2 parse dontdraw) /bwipp.maxicodeExpectedServiceClass er_tmpl +(123456789^029840^029^029) (mode=2 parse dontdraw) /bwipp.maxicodeBadServiceClass er_tmpl +(123456789^029840^0291^029) (mode=2 parse dontdraw) /bwipp.maxicodeBadServiceClass er_tmpl +(123456789^029840^02912A^029) (mode=2 parse dontdraw) /bwipp.maxicodeBadServiceClass er_tmpl + % Figures (THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL...) (mode=4 dontdraw newencoder) % Figure 2 (and L1), same