I am uploading a NMU in order to fix this.
The debdiff is attached.
diff -Nru zmakebas-1.2/bugs12.bas zmakebas-1.2b/bugs12.bas
--- zmakebas-1.2/bugs12.bas 1970-01-01 01:00:00.000000000 +0100
+++ zmakebas-1.2b/bugs12.bas 2021-12-21 23:16:20.000000000 +0100
@@ -0,0 +1,24 @@
+# Tests for various version 1.2/1.2a bugs since fixed.
+# Does DEF FN, VAL$, and line-continuation at EOF.
+#
+# (See e.g. https://bugs.launchpad.net/ubuntu/+source/zmakebas/+bug/1908289
+# for more on 1.2's DEF FN bug.)
+#
+# The last line intentionally ends with a backslash, it's one of the
+# bug tests. If that hangs it, remove to check the others. If you do
+# that then try the output from 1.2 (not 1.2a), RUN will give "Q
+# Parameter error", as will GO TO 50 and GO TO 60. GO TO 70 will give
+# "C Nonsense in BASIC".
+#
+# 1.2a will give multiple question marks from line 90's LIST.
+
+10 def fn a(x)=x*x
+20 def fn b(x,y)=x*y
+30 def fn a$(x$)=x$+x$
+40 print fn a(2);" should be 4"
+50 print fn b(2,3);" should be 6"
+60 print fn a$("foo");" should be foofoo"
+70 print val$ """foo""+""bar""";" should be foobar"
+80 print '"Should LIST 100 with no ?:"''
+90 list 100
+100 def fn c()=(0)\
diff -Nru zmakebas-1.2/ChangeLog zmakebas-1.2b/ChangeLog
--- zmakebas-1.2/ChangeLog 2004-07-23 14:13:43.000000000 +0200
+++ zmakebas-1.2b/ChangeLog 2021-12-21 23:19:15.000000000 +0100
@@ -1,3 +1,61 @@
+2021-12-21 Russell Marks <[email protected]>
+
+ * Version 1.2b.
+
+ * bugs12.bas: fixed incorrect comment about LIST result, it was
+ only version 1.2a that had the relevant issue.
+
+2021-12-19 Russell Marks <[email protected]>
+
+ * README: slight update for new version.
+
+ * zmakebas.1: version bump.
+
+ * bugs12.bas: updated to add a test of sorts for the latest DEF FN
+ bugfix.
+
+ * zmakebas.c: fix for failing to spot the end of DEF FN
+ parameters. Thanks to Chris Born for reporting this bug.
+
+2021-07-04 Russell Marks <[email protected]>
+
+ * Version 1.2a.
+
+ * zmakebas.c: fixed possible buffer overruns. The remaining uses
+ of strcpy look reasonable. There is one use of sprintf I'd prefer
+ to replace with snprintf, but for some platforms it might be
+ unhelpful to require that. It's only used to get a known-4-digit
+ line number, so realistically it should be fine.
+
+2021-07-03 Russell Marks <[email protected]>
+
+ * README: small tweaks, and noting that other versions are around.
+
+ * Makefile: updated to avoid warnings on more recent gcc, and use
+ a more usual man page location and file permissions.
+
+ * zmakebas.1: minor tweaks to update it, and made option listing
+ more consistent.
+
+ * bugs12.bas: tests for various bugs in 1.2, which are now fixed.
+
+ * Fixed line-continuation bug, it got confused if it hit EOF in
+ certain circumstances and could loop indefinitely.
+
+ * Made input buffer sizes capable of handling Basic lines larger
+ than a 48k Spectrum can load. So if you want to embed substantial
+ binary data like machine code in a REM statement you should now be
+ able to. Thanks to Paul Humphreys for his version that suggested
+ this would be useful, though I went a bit bigger. :-)
+
+ * Included DEF FN fix based on Antonio Villena's version. I
+ altered it slightly to avoid the sequence-point issue.
+
+2021-06-27 Russell Marks <[email protected]>
+
+ * Fixed non-parsing of VAL$. Thanks to Andy J for pointing this
+ out.
+
2004-07-23 Russell Marks <[email protected]>
* Version 1.2.
diff -Nru zmakebas-1.2/debian/changelog zmakebas-1.2b/debian/changelog
--- zmakebas-1.2/debian/changelog 2023-10-22 23:37:41.000000000 +0200
+++ zmakebas-1.2b/debian/changelog 2023-10-22 23:29:09.000000000 +0200
@@ -1,3 +1,12 @@
+zmakebas (1.2b-0.1) unstable; urgency=medium
+
+ * Non-maintainer upload.
+ * Update to new upstream version. (Closes: #1017991)
+ * Convert to source format 3.0. (Closes: #1007306)
+ * Use Priority: optional over extra.
+
+ -- Bastian Germann <[email protected]> Sun, 22 Oct 2023 23:29:09 +0200
+
zmakebas (1.2-1.1) unstable; urgency=low
* Non-maintainer upload.
diff -Nru zmakebas-1.2/debian/control zmakebas-1.2b/debian/control
--- zmakebas-1.2/debian/control 2023-10-22 23:37:41.000000000 +0200
+++ zmakebas-1.2b/debian/control 2023-10-22 23:29:09.000000000 +0200
@@ -1,7 +1,7 @@
Source: zmakebas
Maintainer: Krystian Wlosek <[email protected]>
Section: otherosfs
-Priority: extra
+Priority: optional
Standards-Version: 3.7.2
Build-Depends: debhelper (>= 8)
diff -Nru zmakebas-1.2/debian/copyright zmakebas-1.2b/debian/copyright
--- zmakebas-1.2/debian/copyright 2023-10-22 23:37:41.000000000 +0200
+++ zmakebas-1.2b/debian/copyright 2023-10-22 23:29:09.000000000 +0200
@@ -2,7 +2,7 @@
into ZX Spectrum Basic programs. It was Debianised by
Krystian Wlosek <[email protected]>, and uploaded by Piotr
Roszatycki <[email protected]>, using files obtained from
-<URL:ftp://ftp.ibiblio.org/pub/Linux/system/emulators/zx/zmakebas-1.1.tar.gz>.
+<https://zgedneil.nfshost.com/zmakebas.html>.
More information about convert text files into ZX Spectrum Basic programs
is available from <URL:http://rus.members.beeb.net/zmakebas.html>
diff -Nru zmakebas-1.2/debian/source/format zmakebas-1.2b/debian/source/format
--- zmakebas-1.2/debian/source/format 1970-01-01 01:00:00.000000000 +0100
+++ zmakebas-1.2b/debian/source/format 2023-10-22 23:28:46.000000000 +0200
@@ -0,0 +1 @@
+3.0 (quilt)
diff -Nru zmakebas-1.2/Makefile zmakebas-1.2b/Makefile
--- zmakebas-1.2/Makefile 2004-05-01 18:04:56.000000000 +0200
+++ zmakebas-1.2b/Makefile 2021-12-19 02:34:03.000000000 +0100
@@ -1,17 +1,17 @@
# makefile for zmakebas
# comment out the `-DHAVE_GETOPT' if, for some reason or other, you
-# don't have getopt(). (This is mainly so it'll work on MS-DOG, though
+# don't have getopt(). (This is mainly so it'll work on MS-DOS, though
# I'm not entirely sure why I bothered supporting that. :-))
#
CC=gcc
-CFLAGS=-O -Wall -DHAVE_GETOPT
+CFLAGS=-O -Wall -Wno-pointer-sign -DHAVE_GETOPT
# these set where the executable and man page are installed
PREFIX=/usr/local
BINDIR=$(PREFIX)/bin
-MANDIR=$(PREFIX)/man/man1
+MANDIR=$(PREFIX)/share/man/man1
all: zmakebas
@@ -23,8 +23,8 @@
/bin/sh ./mkinstalldirs $(BINDIR) $(MANDIR)
install: zmakebas installdirs
- install -m 511 zmakebas $(BINDIR)
- install -m 444 zmakebas.1 $(MANDIR)
+ install -m 755 zmakebas $(BINDIR)
+ install -m 644 zmakebas.1 $(MANDIR)
uninstall:
$(RM) $(BINDIR)/zmakebas
@@ -36,7 +36,7 @@
# The stuff below makes the distribution tgz.
-VERS=1.2
+VERS=1.2b
dist: tgz
tgz: ../zmakebas-$(VERS).tar.gz
diff -Nru zmakebas-1.2/README zmakebas-1.2b/README
--- zmakebas-1.2/README 2004-07-23 14:14:18.000000000 +0200
+++ zmakebas-1.2b/README 2021-12-19 02:52:55.000000000 +0100
@@ -1,4 +1,4 @@
-zmakebas 1.2 - convert text files into Spectrum Basic programs.
+zmakebas 1.2b - convert text files into Spectrum Basic programs.
Public domain by Russell Marks.
@@ -40,11 +40,28 @@
using labels is in `demolbl.bas', which can be converted with
`zmakebas -l demolbl.bas'.
+The `bugs12.bas' file just demonstrates bugs in earlier versions of
+zmakebas (mostly version 1.2) which were since fixed.
+
+
+Versions
+--------
+
+zmakebas is pretty old now, and I'm generally happy to leave further
+development to others at this point. Indeed this has already happened,
+various forks and versions of zmakebas exist nowadays.
+
+This version is purely intended as a bugfix release for my version 1.2
+from 2004. I have deliberately kept the version below 1.3 and not
+changed things too much, so as to hopefully limit any resulting
+confusion. The intent is really to make my old version easily
+available, while also including fixes for the bugs I'm aware of.
+
Contacting me
-------------
-You can email me at [email protected].
+You can email me at [email protected].
Share and enjoy!
diff -Nru zmakebas-1.2/zmakebas.1 zmakebas-1.2b/zmakebas.1
--- zmakebas-1.2/zmakebas.1 2004-05-01 18:02:09.000000000 +0200
+++ zmakebas-1.2b/zmakebas.1 2021-12-19 02:52:02.000000000 +0100
@@ -5,7 +5,7 @@
.\"
.\" zmakebas.1 - man page
.\"
-.TH zmakebas 1 "1st May, 2004" "Version 1.2" "Retrocomputing Tools"
+.TH zmakebas 1 "19th December, 2021" "Version 1.2b" "Retrocomputing Tools"
.\"
.\"------------------------------------------------------------------
.\"
@@ -15,7 +15,6 @@
.\"------------------------------------------------------------------
.\"
.SH SYNOPSIS
-.PD 0
.B zmakebas
.RB [ -hlr ]
.RB [ -a
@@ -29,8 +28,7 @@
.RB [ -s
.IR line ]
.RI [ input_file ]
-.P
-.PD 1
+.PP
.\"
.\"------------------------------------------------------------------
.\"
@@ -55,35 +53,35 @@
.\"
.SH OPTIONS
.TP
-.I -a
+.B -a
make the generated file auto-start from line
.IR startline .
If `-l' was specified, this can be a label, but don't forget to
include the initial `@' to point this out.
.TP
-.I -h
+.B -h
give help on command line options.
.TP
-.I -i
+.B -i
in labels mode, set line number increment (default 2).
.TP
-.I -l
+.B -l
use labels rather than line numbers.
.TP
-.I -n
+.B -n
specify filename to use in .TAP file (up to 10 chars), i.e. the
filename the speccy will see. Default is a blank filename (10 spaces).
.TP
-.I -o
+.B -o
output to
.I output_file
rather than the default `out.tap'. Use `-' as the filename to output
on stdout.
.TP
-.I -r
+.B -r
write a raw headerless Basic file, rather than the default .TAP file.
.TP
-.I -s
+.B -s
in labels mode, set starting line number (default 10).
.\"
.\"------------------------------------------------------------------
@@ -227,11 +225,9 @@
.\"------------------------------------------------------------------
.\"
.SH "SEE ALSO"
-.IR fuse "(1),"
-.IR xz80 "(1),"
-.IR xzx "(1)"
+.BR fuse "(1)"
.\"
.\"------------------------------------------------------------------
.\"
.SH AUTHOR
-Russell Marks ([email protected]).
+Russell Marks ([email protected]).
diff -Nru zmakebas-1.2/zmakebas.c zmakebas-1.2b/zmakebas.c
--- zmakebas-1.2/zmakebas.c 2004-05-01 17:53:33.000000000 +0200
+++ zmakebas-1.2b/zmakebas.c 2021-12-19 02:53:44.000000000 +0100
@@ -27,12 +27,18 @@
#define REM_TOKEN_NUM 234
#define BIN_TOKEN_NUM 196
+#define VAL_TOKEN_NUM 176
+#define VALSTR_TOKEN_NUM 174
+#define DEFFN_TOKEN_NUM 206
/* tokens are stored (and looked for) in reverse speccy-char-set order,
* to avoid def fn/fn and go to/to screwups. There are two entries for
* each token - this is to allow for things like "go to" which can
* actually be entered (thank ghod) as "goto". The one extension to
* this I've made is that randomize can be entered with -ize or -ise.
+ *
+ * One exception to the above - VAL/VAL$ positions are flipped here
+ * so that we do VAL$ first, and swapped after tokenising.
*/
char *tokens[]=
{
@@ -115,9 +121,9 @@
"cos", "",
"sin", "",
"len", "",
- "val", "",
- "code", "",
"val$", "",
+ "code", "",
+ "val", "",
"tab", "",
"at", "",
"attr", "",
@@ -380,7 +386,7 @@
void usage_help()
{
-printf("zmakebas - public domain by Russell Marks.\n\n");
+printf("zmakebas 1.2b - public domain by Russell Marks.\n\n");
printf("usage: zmakebas [-hlr] [-a line] [-i incr] [-n speccy_filename]\n");
printf(" [-o output_file] [-s line] [input_file]\n\n");
@@ -443,7 +449,10 @@
speccy_filename[10]=0;
break;
case 'o':
- strcpy(outfile,optarg);
+ if(strlen(optarg)>sizeof(outfile)-1)
+ fprintf(stderr,"Filename too long\n"),exit(1);
+ else
+ strcpy(outfile,optarg);
break;
case 'r': /* output raw file */
output_tap=0; break;
@@ -484,7 +493,12 @@
usage_help(),exit(1);
if(optind==argc-1) /* one remaining arg */
- strcpy(infile,argv[optind]);
+ {
+ if(strlen(argv[optind])>sizeof(infile)-1)
+ fprintf(stderr,"Filename too long\n"),exit(1);
+ else
+ strcpy(infile,argv[optind]);
+ }
}
@@ -524,9 +538,19 @@
#ifdef MSDOS
static unsigned char buf[512],lcasebuf[512],outbuf[1024];
#else
-static unsigned char buf[2048],lcasebuf[2048],outbuf[4096];
+/* deliberately very large buffers, to allow e.g. embedding of m/c
+ * programs in REM statements. 48k*8 should cover all eventualities,
+ * and not generally be a problem at this point. I mean, it's not
+ * even a megabyte in total, what's that between friends? :-)
+ *
+ * Note that these need to be large even if line-continuation
+ * backslashes are used, as the line is constructed in buf[]. outbuf
+ * is in the Spectrum's tokenised format, and can be much smaller.
+ */
+static unsigned char buf[8*49152],lcasebuf[8*49152];
+static unsigned char outbuf[49152];
#endif
-int f,toknum,toklen,linenum,linelen,in_quotes,in_rem,lastline;
+int f,toknum,toklen,linenum,linelen,in_quotes,in_rem,in_deffn,lastline;
char **tarrptr;
unsigned char *ptr,*ptr2,*linestart,*outptr,*remptr,*fileptr,*asciiptr;
double num;
@@ -576,13 +600,20 @@
*/
if(buf[1]==0 || buf[1]=='#') continue;
- /* check for line continuation */
- while(buf[strlen(buf)-1]=='\\')
+ /* check for line continuation; the "*buf" checks here aren't strictly
+ * necessary (see buf[0] above) but I'm just happier this way. :-)
+ */
+ while(*buf && buf[strlen(buf)-1]=='\\' && !feof(in))
{
f=strlen(buf)-1;
- fgets(buf+f,sizeof(buf)-f,in);
- textlinenum++;
- if(buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1]=0;
+ if(fgets(buf+f,sizeof(buf)-f,in))
+ textlinenum++;
+ else
+ {
+ if(*buf) buf[strlen(buf)-1]=0; /* remove backslash on EOF */
+ }
+
+ if(*buf && buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1]=0;
}
if(strlen(buf)>=sizeof(buf)-MAX_LABEL_LEN-1)
@@ -732,6 +763,11 @@
{
if(alttok) toknum--;
alttok=!alttok;
+ switch(toknum)
+ {
+ case VAL_TOKEN_NUM: toknum=VALSTR_TOKEN_NUM; break;
+ case VALSTR_TOKEN_NUM: toknum=VAL_TOKEN_NUM;
+ }
if(**tarrptr==0) continue;
toklen=strlen(*tarrptr);
ptr=lcasebuf;
@@ -797,7 +833,7 @@
if(memcmp(labels[f],ptr,len)==0 &&
(ptr[len]<33 || ptr[len]>126 || ptr[len]==':'))
{
- unsigned char numbuf[20];
+ static unsigned char numbuf[64];
/* this could be optimised to use a single memmove(), but
* at least this way it's clear(er) what's happening.
@@ -828,7 +864,7 @@
/* remove 0x01s, deal with backslash things, and add numbers */
ptr=linestart;
outptr=outbuf;
- in_rem=in_quotes=0;
+ in_rem=in_deffn=in_quotes=0;
while(*ptr)
{
@@ -847,6 +883,8 @@
continue;
}
+ if(*ptr==DEFFN_TOKEN_NUM) in_deffn=1;
+
if(*ptr==REM_TOKEN_NUM) in_rem=1;
if(*ptr=='\\')
@@ -941,8 +979,38 @@
}
else
{
- /* if not number, just output char */
- *outptr++=*ptr++;
+ /* special def fn case */
+ if(in_deffn)
+ {
+ if(*ptr=='=')
+ in_deffn=0;
+ else
+ {
+ if(*ptr==',' || *ptr==')')
+ {
+ *outptr++=0x0e;
+ *outptr++=0;
+ *outptr++=0;
+ *outptr++=0;
+ *outptr++=0;
+ *outptr++=0;
+ *outptr++=*ptr++;
+ }
+
+ if(*ptr!=' ')
+ {
+ if(*ptr=='=')
+ in_deffn=0;
+
+ *outptr++=*ptr++;
+ }
+ }
+ }
+ else
+ {
+ /* if not number, just output char */
+ *outptr++=*ptr++;
+ }
}
}