Add the %num() preprocessor function, which returns a quoted string
with a number formatted in any base between 2 and 64 (using bash
encoding with '@' for 62 and '_' for 63.)
It can specify a fixed number of digits with or without truncation.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Classify all remaining WARN_OTHER warnings in the preprocessor. Move
all preprocessor warnings except "user" under a common pp-* prefix.
Warn for an out-of-range argument to the %sel() function.
Finally, use "dname" in additional places for consistency and future
ease of use.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Implement the %cond() and %sel() functions that expand to a specific
one of the arguments. %cond(x,y,z) is basically a shorthand for
%sel(2-!(x),y,z) used when x is a boolean condition.
Fix a memory leak in %strcat and %strlen.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Allow preprocessor function expansion to recurse. Nearly all the
machinery for recursive smacros was already in place; this merely
activates it for the specific case of preprocessor functions. Making
it a general facility should be deferred to a later relese, though.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Some preprocessor functions have the same name as directives. In those
cases, they should be expanded as functions if and only if they are
followed by a left parenthesis. Although it is not inherently true that
either preprocessor functions require a paren nor that directives
cannot start with one, but it is true and will remain true for all
cases where there is a namespace collision.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
%substr contained a token skip to "skip expanded ID", which is
incorrect, as that has already been skipped at that point. It worked
anyway, accidentally, as this token would always be a whitespace token
-- but we then do skip_white() immediately thereafter.
Delete this to allow this code to be factored.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit adds a check to see if the macro that we want to unmacro exists.
A previous commit, introduced a check to see if the unmacro was undefining a macro being expanded, but that same check included a null pointer dereference if the macro to undefine did not exist.
The following code reproduced the issue:
```asm
%macro baz 0
%unmacro F 0
%endmacro
baz
```
Compile with:
```shell
$ nasm -f elf64 -g -FDWARF -o tmp.o -werror file.asm
```
[hpa: adjusted code to match NASM style]
Fixes bug 3392761
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This reverts commit 8fcc785f95b842694015e03d909a3131cbadbeb3.
This patch causes test a32offs.asm, and in general *any* use of the
"bits" macro, to totally fail.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
case PP_ENDM:
case PP_ENDMACRO:
if (!(defining && defining->name)) {
nasm_nonfatal("`%s': not defining a macro", tok_text(tline));
goto done;
}
mmhead = (MMacro **) hash_findi_add(&mmacros, defining->name);
defining->next = *mmhead;
*mmhead = defining;
defining = NULL;
break;
The variable: mmacros has not been released, which will cause a memory
leak. Repair cve-2021-33450 cve-2021-33452 synchronously
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
free() and nasm_free() are required to be compatible (as we may end up
having memory allocated on the heap by the C library), but that
doesn't mean we shouldn't use it whereever possible to allow for
better debugging.
Fixes: https://bugzilla.nasm.us/show_bug.cgi?id=3392804
Reported-by: C. Masloch <pushbx@ulukai.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
An empty %{} becomes % which is simply the arithmetic
operator. Although that is consistent, it might be surprising for
users, to issue a warning.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
%[] amounts to an empty token; this needs to be handled specially so
that it gets properly dropped.
Fixes: https://bugzilla.nasm.us/show_bug.cgi?id=3392806
Reported-by: C. Masloch <pushbx@ulukai.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Regression in commit 20e0d616dc954d567c8bf2c7e11cc5d6c10ac544.
Independently discovered and fixed by C. Masloch:
https://bugzilla.nasm.us/show_bug.cgi?id=3392747
Signed-off-by: Oleg Oshmyan <chortos@inbox.lv>
Make the pasting behavior of TOKEN_QMARK, TOKEN_HERE and TOKEN_BASE
match the NASM 2.15 behavior: ? is a keyword and pastes as an ID, $
and $$ are treated as operators (which doesn't seem to make much
sense, but it is the current legacy behavior.)
Reported-by: C. Masloch <pushbx@ulukai.org>
Bugzilla: https://bugzilla.nasm.us/show_bug.cgi?id=3392733
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
If macro is undefined while it's being expanded, use after free occurs,
since the MMacro instance is released, but it is still used to proceed
the expansion.
This change forbids macro undefinition: non-fatal error is raised and
the MMacro instance is not released if it is being processed by NASM
preprocessor.
Consider the following example:
| $ cat test.asm
| %macro m 0
| %unmacro m 0
| %endmacro
| m
| $ ./nasm test.asm
| test.asm:4: error: `%unmacro' can't undefine the macro being expanded
| test.asm:2: ... from macro `m' defined here
Fixes BR3392531 and BR3392716.
Signed-off-by: Igor Munkin <imun@cpan.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Better point out explicitly that SMacro::next member
is untouched, thus do not use SMacro::next and an array.
CID 1432925
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
When we process a TOKEN_QMARK we also need to advance p, in order to
get the proper start for the next token.
This fixes travis test br3392707.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
The operation of the ',' and ')' tokens are very similar, except for:
',' issues a error if the processed parameter is greedy;
')' sets the "done" variable.
The code would incorrectly set "done" for a ',' token. This fixes
travis test br3392711.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
When pasting and stripping %+ and whitespace tokens, we either need to
set *nextp in the loop, or treat next as a separate variable and
update *nextp after the loop finishes. This implements the second
option.
This fixes travis test "amx".
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Add the %eval() preprocessor function. It evaluates each of its
arguments like a number and expands to a comma-separated lists of the
evaluated arguments.
To support this, add the concept of "true varadic" macros, which are
only used internally. True varadic macros differ from greedy macros in
that the parameter list is still parsed as individual parameters and
provided to the expansion function. As this isn't meaningful for
user-defined macros, there is no way to specify it from a directive.
Add back the %isnfoo() functions. Although one could just as well write
!%isfoo(), it doesn't cost much to provide them, and might help avoid
programmer confusion.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
%ifid $ and %ifid $$ has traditionally been false, revert to that
behavior.
Reported-by: Mike Hommey <mh+anfz@glandium.org>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
NASM 2.15.04
Conflicts:
asm/listing.h
asm/pptok.pl
asm/preproc.c
version
This doesn't pass travis test 3392711, which is using an extremely odd
construct of %?? in the middle of an argument sequence for an smacro
while not being in a macro itself, and expecting it to expand to the
macro name. This seems to *really* confuse the master branch.
Resolve this later...
At least DWARF can encode C-style macros. In doing so, it wants the
file include hierarchy, so give the debug format backend the option of
receiving that information from the preprocessor.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
The mempcpy helper returns *last* byte pointer thus when
we call set_text_free we have to pass a pointer to the
start of the string.
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Make sure the data being freed get double
freed after -- the pointers must be zapped
(actually nasm_free and free_tlist support
being called with NULL pointer as an argument).
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
After issuing an error message for a missing %stacksize argument, need
to quit rather than continuing to try to access the pointer.
Fold uses of tok_text() while we are at it.
Reported-by: Suhwan <prada960808@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
The %? and %?? tokens are ambiguous when used inside a multi-line
macro. Add tokens %*? and %*?? that only expand during single-macro
expansion.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
If macros are nolisted, *or* they don't have any filename associated
with them, it is absolutely pointless to try to descend into them for
error messages, so just don't, even if -Lb is provided.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
The previous code to fix whitespace around and multiple %+ symbols in
a row (checkin 122c5fb75986adc37dfb147cc2a613e3ebc66e80) had some
seriously broken pointer handling when zapping tokens. This could
cause paste_tokens() to go into an infinite loop because it would
attach %+ to another token and then immediately break them apart
again, over and over.
Reported-by: <alexfru@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
The different token codes between the preprocessor and the assembler
is a completely unnecessary headache. Furthermore, lumping all the
operators under TOK_OTHER in the preprocessor causes a whole bunch of
unnecessary headaches.
In combining them, the only tricky part is that PP_CONCAT_MASK() is no
longer usable, as the range of token codes is too large. Replace with
dedicated category masks.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
To handle escape codes in filename strings after # markers correctly,
we need nasm_unquote() to be aware that it is using C escapes;
otherwise things like "foo`bar" will break.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
In 41e9682efed7cd1df133b1b4ac806e07723f1486 we've
changed the nasm_quote arguments still not all callers
were converted which could lead to nil dereference.
[hpa: no need to call strlen() for the asm/preproc.c chunk]
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Add the first "preprocessor functions". These are simply "magic"
single-line macros with a suitable expansion function. The first
application is functions equal to the %if directives, e.g.
%ifdef blah == %if %isdef(blah) except can be used anywhere (not just
in %if statements like defined() in C.)
Signed-off-by: H. Peter Anvin <hpa@zytor.com>