shithub: rgbds

Download patch

ref: 937c9888a4ed4269ee9d9f7ad4d697649b7f0ad1
parent: 61a9bfd33cf9e620a39c337291adc69b9558ff57
author: Jakub Kądziołka <[email protected]>
date: Wed Mar 31 11:03:57 EDT 2021

Robustly disallow overwriting builtin symbols (#817)


--- a/src/asm/symbol.c
+++ b/src/asm/symbol.c
@@ -379,6 +379,7 @@
 		error("'%s' already defined at ", symbolName);
 		dumpFilename(symbol);
 		putc('\n', stderr);
+		return NULL; // Don't allow overriding the symbol, that'd be bad!
 	} else if (!numeric) {
 		// The symbol has already been referenced, but it's not allowed
 		error("'%s' already referenced at ", symbolName);
@@ -439,6 +440,10 @@
 		error("'%s' already defined as non-EQUS at ", symName);
 		dumpFilename(sym);
 		putc('\n', stderr);
+		return NULL;
+	} else if (sym->isBuiltin) {
+		error("Built-in symbol '%s' cannot be redefined\n", symName);
+		return NULL;
 	}
 
 	/*
--- /dev/null
+++ b/test/asm/builtin-overwrite.asm
@@ -1,0 +1,43 @@
+macro tickle
+; There once was a bug where overwriting worked only on the second try, so
+; try everything twice for good measure
+
+; Skip this syntax for EQUS, as it is invalid
+IF \2
+\1 = 0
+\1 = 0
+PRINTLN \1
+
+\1 EQU 0
+\1 EQU 0
+PRINTLN \1
+ENDC
+
+PURGE \1
+PURGE \1
+PRINTLN \1
+
+DEF \1 EQU 0
+DEF \1 EQU 0
+PRINTLN \1
+
+DEF \1 = 0
+DEF \1 = 0
+PRINTLN \1
+
+DEF \1 EQUS "hello"
+DEF \1 EQUS "hello"
+PRINTLN \1
+
+REDEF \1 = 0
+REDEF \1 = 0
+PRINTLN \1
+
+REDEF \1 EQUS "hello"
+REDEF \1 EQUS "hello"
+PRINTLN \1
+endm
+
+    ; Representative numeric and string builtins
+    tickle __LINE__, 1
+    tickle __FILE__, 0
--- /dev/null
+++ b/test/asm/builtin-overwrite.err
@@ -1,0 +1,57 @@
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(7):
+    '__LINE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(8):
+    '__LINE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(11):
+    '__LINE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(12):
+    '__LINE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(16):
+    Built-in symbol '__LINE__' cannot be purged
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(17):
+    Built-in symbol '__LINE__' cannot be purged
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(20):
+    '__LINE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(21):
+    '__LINE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(24):
+    '__LINE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(25):
+    '__LINE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(28):
+    '__LINE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(29):
+    '__LINE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(32):
+    '__LINE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(33):
+    '__LINE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(36):
+    '__LINE__' already defined as non-EQUS at <builtin>
+ERROR: builtin-overwrite.asm(42) -> builtin-overwrite.asm::tickle(37):
+    '__LINE__' already defined as non-EQUS at <builtin>
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(16):
+    Built-in symbol '__FILE__' cannot be purged
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(17):
+    Built-in symbol '__FILE__' cannot be purged
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(20):
+    '__FILE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(21):
+    '__FILE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(24):
+    '__FILE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(25):
+    '__FILE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(28):
+    '__FILE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(29):
+    '__FILE__' already defined at <builtin>
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(32):
+    '__FILE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(33):
+    '__FILE__' already defined as constant at <builtin>
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(36):
+    Built-in symbol '__FILE__' cannot be redefined
+ERROR: builtin-overwrite.asm(43) -> builtin-overwrite.asm::tickle(37):
+    Built-in symbol '__FILE__' cannot be redefined
+error: Assembly aborted (28 errors)!
--- /dev/null
+++ b/test/asm/builtin-overwrite.out
@@ -1,0 +1,14 @@
+$9
+$D
+$12
+$16
+$1A
+$1E
+$22
+$26
+builtin-overwrite.asm
+builtin-overwrite.asm
+builtin-overwrite.asm
+builtin-overwrite.asm
+builtin-overwrite.asm
+builtin-overwrite.asm
--- a/test/asm/narg-overwrite.asm
+++ /dev/null
@@ -1,2 +1,0 @@
-_NARG = 0
-_NARG = 0
--- a/test/asm/narg-overwrite.err
+++ /dev/null
@@ -1,5 +1,0 @@
-ERROR: narg-overwrite.asm(1):
-    '_NARG' already defined as constant at <builtin>
-ERROR: narg-overwrite.asm(2):
-    '_NARG' already defined as constant at <builtin>
-error: Assembly aborted (2 errors)!