Giter Club home page Giter Club logo

picoc's Introduction

Originally forked from https://github.com/zsaleeba/picoc

Description

PicoC is a very small C interpreter for scripting. It was originally written as a script language for a UAV on-board flight system. It's also very suitable for other robotic, embedded and non-embedded applications.

The core C source code is around 3500 lines of code. It's not intended to be a complete implementation of ISO C but it has all the essentials. When compiled it only takes a few k of code space and is also very sparing of data space. This means it can work well in small embedded devices. It's also a fun example of how to create a very small language implementation while still keeping the code readable.

It's been tested on x86-32, x86-64, powerpc, arm, ultrasparc, HP-PA and blackfin processors and is easy to port to new targets.

Running files from the command line

You can run standard C programs straight from the command line:

$ picoc file.c

If your program is split into multiple files you can list them all on the command line.

$ picoc file1.c file2.c file3.c

If your program takes arguments you add them after a '-' character.

$ picoc file.c - arg1 arg2

Running script files

Scripts are slightly simpler than standard C programs because, A) all the system headers are included automatically for you so you don't need to include them in your file/s and B) scripts don't require a main() function; they have statements that are run directly from the top of a file to the bottom.

$ picoc -s file.c

Here's an example script:

printf("Starting my script\n");

int i;
int total = 0;
for (i = 0; i < 10; i++) {
    printf("i = %d\n", i);
    total += i;
}

printf("The total is %d\n", total);

Here's the output from this script:

$ ./picoc -s script.c
Starting my script
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
The total is 45

Interactive mode

> picoc -i

Here's an example session:

$ ./picoc -i
starting picoc v2.1
picoc> char inbuf[80];
picoc> gets(inbuf);
hello!
picoc> printf("I got: %s\n", inbuf);
I got: hello!

Deleting variables and functions.

Sometimes in interactive mode you want to change a function or redeclare a variable. You can do this using the "delete" statement:

$ ./picoc -i
starting picoc v2.1
picoc> int fred = 1234;
picoc> printf("fred = %d\n", fred);
fred = 1234
picoc> delete fred;
picoc> char *fred = "hello";
picoc> printf("fred = '%s'\n", fred);
fred = 'hello'

Note, you can quit picoc's interactive mode using control-D.

Environment variables

In some cases you may want to change the picoc stack space. The default stack size is 512KB (see PICOC_STACK_SIZE in picoc.c) which should be large enough for most programs.

To change the stack size you can set the STACKSIZE environment variable to a different value. The value is in bytes.

Compiling PicoC

picoc can be compiled for a UNIX/Linux/POSIX host by typing "make".

The test suite can be run by typing "make test".

On Windows, use the MSVC++ sln file in the msvc/picoc folder.

Porting PicoC

platform.h is where you select your platform type and specify the includes etc. for your platform.

platform_XXX.c contains support functions so the compiler can work on your platform, such as how to write characters to the console etc..

platform_library.c contains your library of functions you want to make available to user programs.

There's also a clibrary.c which contains user library functions like printf() which are platform-independent.

Porting the system will involve setting up suitable includes and defines in platform.h, writing some I/O routines in platform_XXX.c, putting whatever user functions you want in platform_library.c and then changing the main program in picoc.c to whatever you need to do to get programs into the system.

platform.h is set to UNIX_HOST by default so tests can be easily run on a UNIX system. You'll need to specify your own host setup dependent on your target platform.

Copyright

PicoC is published under the "New BSD License", see the LICENSE file.

Adding native C functions

Introduction

picoc allows you to define your own library functions. These functions are written in C using your system's native C compiler. Since the native C compiler can access the hardware this means you can add functions which give picoc control of your hardware.

How libraries work

Your picoc distribution contains two files which are used to define library functions for your system. If your system is called "foobar" you'll be using:

  • library_foobar.c - this is where the foobar-specific library functions go
  • clibrary.c - this is where standard C library functions like printf() are defined

We'll start by defining a simple function in library_foobar.c. We need to do two things:

  • add the function prototype to our list of picoc library functions
  • define the native C implementation of the function

The prototype list

Each of the library_XXX.c files defines a list of picoc prototypes for each of the functions it defines. For example:

struct LibraryFunction PlatformLibrary[] =
{
     {ShowComplex,  "void ShowComplex(struct complex *)"},
     {Cpeek,        "int peek(int, int)"},
     {Cpoke,        "void poke(int, int, int)"},
     {Crandom,      "int random(int)"},
     {NULL,         NULL}
};

The first column is the name of the C function. The second column is the function prototype. The "{ NULL, NULL }" line at the end is required.

The native C function

The native C function is called with these parameters:

void MyCFunc(struct ParseState *Parser,
			 struct Value *ReturnValue,
			 struct Value **Param,
			 int NumArgs);
  • struct ParseState *Parser - this contains internal information about the progress of parsing. It's mostly used here so error messages from your function can report the line number where an error occurred.
  • struct Value *ReturnValue - this points to the place you can put your return value. This is pre-created as a value of the correct return type so all you have to do is store your result here.
  • struct Value **Param - this points to an array of parameters. These are all pre-checked as being the correct type.
  • int NumArgs - this is the number of parameters. Normally this will already have been checked and will be exactly what you've defined in your function prototype. It is however possible to define functions with variable numbers of arguments using a stdarg-like "..." method and this is where you find out how many parameters were passed in if you're doing that.

Here's an example function definition of "random" (as defined above):

void Crandom(struct ParseState *Parser,
			 struct Value *ReturnValue,
			 struct Value **Param,
			 int NumArgs)
{
    ReturnValue->Val->Integer = random() % Param[0]->Val->Integer;
}

This function calls "random()" from the C standard library. It accesses an integer parameter and returns an integer value.

Passing parameters

We've seen how to pass integers into functions. What about passing other data types?

Type Method Comment
int Param[x]->Val->Integer
char Param[x]->Val->Integer Treated as 'int' here
double Param[x]->Val->FP Only available on some systems
float Param[x]->Val->FP Same as 'double'
enum Param[x]->Val->Integer Gives integer value of enum
pointers See section below Slightly more complicated
char * See section below Slightly more complicated
arrays See section below Slightly more complicated
struct See section below Slightly more complicated
union See section below Slightly more complicated

Passing pointers

Pointer parameters are slighty more complicated to access since you have to dereference the pointer to get at the underlying data.

Here's how we dereference a pointer parameter. In this example I'll be reading an 'int *' parameter:

int IntValue = *(int*)Param[0]->Val->NativePointer;

Passing strings/char*

In this example I'll be reading a 'char *' parameter. It's pretty similar to the 'int *' example above:

char *CharPtr = (char*)Param[0]->Val->NativePointer;

picoc strings work like C strings - they're pointers to arrays of characters, terminated by a null character. Once you have the C char * you can use it just like a normal C string.

Pointers to arrays of other data types work the same way.

Passing pointers to structures and unions

If you're defining library functions which take structures as parameters you'll have to do a little more work. You need to pre-define the structure so the function prototype can refer to it.

In library_XXX.c you'll find a function called PlatformLibraryInit(). This is called before the library prototypes are defined. Here's a quick way to define a complex number structure as if it was defined in an include file:

IncludeRegister("win32.h",
				&win32SetupFunc,
				&win32Functions[0],
				"struct complex {int i; int j;};");

Or you could just parse the structure directly:

const char *definition = "struct complex {int i; int j;};";
PicocParse("my lib", definition, strlen(definition), true, false, false);

The same method works for defining macros too:

const char *definition = "#define ABS(a) ((a) < (0) ? -(a) : (a))";
PicocParse("my lib", definition, strlen(definition), true, false, false);

Here's a more sophisticated method, using the internal functions of picoc directly:

void PlatformLibraryInit()
{
    struct ParseState Parser;
    char *Identifier;
    struct ValueType *ParsedType;
    void *Tokens;
    char *IntrinsicName = TableStrRegister("complex library");
    const char *StructDefinition = "struct complex { int i; int j; }";

    /* define an example structure */
    Tokens = LexAnalyse(IntrinsicName, StructDefinition, strlen(StructDefinition), NULL);
    LexInitParser(&Parser, StructDefinition, Tokens, IntrinsicName, true, false);
    TypeParse(&Parser, &ParsedType, &Identifier, &IsStatic);
    HeapFree(Tokens);
}

This code takes the structure definition in StructDefinition and runs the lexical analyser over it. This returns some lexical tokens. Then we initialize the parser and have it parse the type of the structure definition from the tokens we made. That's enough to define the structure in the system. Finally we free the tokens.

Now let's say we're going to define a function to display a complex number. Our prototype will look like:

{ShowComplex,   "void ShowComplex(struct complex *)"},

And finally we can define the library function:

struct complex {int i; int j;};  /* make this C declaration match the picoc one */

void ShowComplex(struct ParseState *Parser,
				 struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
    struct complex *ComplexVal = Param[0]->Val->NativePointer;  /* casts the pointer */

    /* print the result */
    PrintInt(ComplexVal->i, PlatformPutc);
    PlatformPutc(',');
    PrintInt(ComplexVal->j, PlatformPutc);
}

Unions work exactly the same way as structures. Define the prototype as "union" rather than "struct" and you're away.

Returning values

Returning values from library functions is very much like accessing parameters. The type of return values is already set before your native C function is called so all you have to do is fill in the value.

Just as with parameters, ints, chars and enums are stored in ReturnValue->Val->Integer and floating point values are returned in ReturnValue->Val->FP.

Returning pointers

Returning a pointer to a static string or some other allocated data is easy. Your return code will look something like:

ReturnValue->Val->NativePointer = "hello";

Variable numbers of parameters

You can define your own stdarg-style library functions like printf(). Your function prototype should use "..." in the parameter list to indicate the potential extra parameters just like the standard stdarg system. Here's an example from clibrary.c:

{LibPrintf, "void printf(char *, ...)"},

The NumArgs parameter to the native C function lets you know how many parameters were passed in. You access the variable parameters just like normal parameters using the Param[] array.

Take a look at clibrary.c for the full definition of LibPrintf() if you need a more complete example.

Sharing native values with PicoC

Sometimes you have native variables you'd like to share with picoc. We can define a picoc value which shares memory with a native variable. Then we store this variable in the picoc symbol table so your programs can find it by name. There's an easy way to do this:

int RobotIsExploding = 0;

void PlatformLibraryInit()
{
    VariableDefinePlatformVar(NULL,
    						  "RobotIsExploding",
    						  &IntType,
    						  (union AnyValue*)&RobotIsExploding,
    						  false);
}

The variable RobotIsExploding can be written by your native C program and read by PicoC just like any other PicoC variable. In this case it's protected from being written by the last parameter "IsWritable" being set to FALSE. Set it to TRUE and PicoC will be able to write it too.

How PicoC differs from C90

PicoC is a tiny C language, not a complete implementation of C90. It doesn't aim to implement every single feature of C90 but it does aim to be close enough that most programs will run without modification.

PicoC also has scripting abilities which enhance it beyond what C90 offers.

C preprocessor

There is no true preprocessor in PicoC. The most popular preprocessor features are implemented in a slightly limited way.

#define

Macros are implemented but have some limitations. They can only be used as part of expressions and operate a bit like functions. Since they're used in expressions they must result in a value.

#if/#ifdef/#else/#endif

The conditional compilation operators are implemented, but have some limitations. The operator "defined()" is not implemented. These operators can only be used at statement boundaries.

#include

Includes are supported however the level of support depends on the specific port of PicoC on your platform. Linux/UNIX and Windows support #include fully.

Function declarations

These styles of function declarations are supported:

int my_function(char param1, int param2, char *param3)
{
   ...
}

int my_function(char param1, int param2, char *param3) {
   ...
}

The old "K&R" form of function declaration is not supported.

Predefined macros

A few macros are pre-defined:

  • PICOC_VERSION - gives the picoc version as a string eg. "v2.1 beta r524"

Function pointers

Pointers to functions are currently not supported.

Storage classes

Many of the storage classes in C90 really only have meaning in a compiler so they're not implemented in picoc. This includes: static, extern, volatile, register and auto. They're recognised but currently ignored.

struct and unions

Structs and unions can only be defined globally. It's not possible to define them within the scope of a function.

Bitfields in structs are not supported.

Linking with libraries

Because picoc is an interpreter (and not a compiler) libraries must be linked with picoc itself. Also a glue module must be written to interface to picoc. This is the same as other interpreters like python.

If you're looking for an example check the interface to the C standard library time functions in cstdlib/time.c.

goto

The goto statement is implemented but only supports forward gotos, not backward. The rationale for this is that backward gotos are not necessary for any "legitimate" use of goto.

Some discussion on this topic:

picoc's People

Contributors

jpoirier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

picoc's Issues

pointer to function

As main gets strings as arguments, it would be interesting to transform some of those strings into calls to functions (for example, associating those strings to function pointers in a lookup array). However, I could find not way to express a pointer to function and run it. For example, let's take a function which takes an int and returns an int. In C, a typedef is usually declared:

typedef int (*pFct)(int);

This construct is unsupported. Moreover, defining a function with such a pointer-to-function is unsupported either. E.g.:

int executeMe(int(*pFct)(int), int val) {return pFct(int);}

Is there a workaround? It could significantly improve scripts in an constrained embedded environment.

If not, and if you can suggest where in the source code this feature could be implemented, I would be happy to try this myself. But maybe this is a fundamentally tough undertaking...

picoc won't build: fatal error: readline/readline.h: No such file or directory

I can't build picoc on Debian:

platform/platform_unix.c:5:31: fatal error: readline/readline.h: No such file or directory
 #include <readline/readline.h>
                               ^
compilation terminated.
<builtin>: recipe for target 'platform/platform_unix.o' failed
make: *** [platform/platform_unix.o] Error 1

I am extremely incompetent at compiling from source, but it sounds to me like some readline.h file is missing. Is there any way to fix this?

Wrong result after shifting unsigned

The following code:

unsigned crc;
crc = 0x80000000;
crc >>= 1;
printf("crc = %X\n", crc);

produces the following output:

crc = C0000000

Which is wrong (should be 4000000)

if ( somepointer) fails

What steps will reproduce the problem?
Simple input to generate the problem using interactive mode:
$ ./picoc -i
picoc> int *i = NULL;
picoc> if (i) printf("i\n"); else printf("NULL\n");

What is the expected output? What do you see instead?
Expected: NULL
Instead: :2:6 integer value expected instead of int*

What version of the product are you using? On what operating system?
OS X, picoc 603

Please provide any additional information below.
The problem is with expression.c:ExpressionParseInt(). The method uses "if (!IS_NUMERIC_COERCIBLE(Val))" to decide if the value can be used. It's legal to use a pointer in this form of if statement as a shorthand form of "if (pointer != NULL)" but this macro doesn't allow for that. Changing the check to the following works but may introduce other problems? if (!IS_NUMERIC_COERCIBLE(Val) && !(Val->Typ->Base == TypePointer))

Note that if (i == NULL) works

Issue copied from: https://code.google.com/p/picoc/issues/detail?id=187

Interactive mode undefined native functions

When compiled with optimizations turned on and in interactive mode functions like printf are undefined.

E.g. create a user function
picoc > void tst() { printf("%d\n", 876); }

Call the function
picoc > tst();

Returns "ExpressionParseFunctionCall FuncName: 'printf' is undefined"

The problem seems to originate in VariableScopeEnd but I've not been able to figure out the problem yet.

Windows build

The version in the repository won't build on Windows. When I built it a few days ago I had to add

typedef __int64				int64_t;
typedef unsigned __int64	uint64_t;

I simply added this to platform.h.

Also, strdup () is not available in the Windows build by default.
I added

#define strdup		_strdup

for this. Then I changed the position of the #ifndef WIN32 within string.c.

Beginning of platform.h:

/* all platform-specific includes and defines go in this file */
#ifndef PLATFORM_H
#define PLATFORM_H

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <setjmp.h>
#include <math.h>
#include <stdbool.h>

/* host platform includes */
#ifdef UNIX_HOST
# include <stdint.h>
# include <unistd.h>
#elif defined(WIN32) /*(predefined on MSVC)*/
typedef __int64				int64_t;
typedef unsigned __int64	uint64_t;
#define strdup		_strdup
#else
# error ***** A platform must be explicitly defined! *****
#endif

Around line 170 within cstdlib/string.h:

void StringStrxfrm(struct ParseState *Parser, struct Value *ReturnValue,
    struct Value **Param, int NumArgs)
{
    ReturnValue->Val->Integer = strxfrm(Param[0]->Val->Pointer,
        Param[1]->Val->Pointer, Param[2]->Val->Integer);
}

void StringStrdup(struct ParseState *Parser, struct Value *ReturnValue,
    struct Value **Param, int NumArgs)
{
    ReturnValue->Val->Pointer = (void*)strdup(Param[0]->Val->Pointer);
}

#ifndef WIN32
void StringStrtok_r(struct ParseState *Parser, struct Value *ReturnValue,
    struct Value **Param, int NumArgs)
{
    ReturnValue->Val->Pointer = (void*)strtok_r(Param[0]->Val->Pointer,
        Param[1]->Val->Pointer, Param[2]->Val->Pointer);
}
#endif

And a bit further down in string.c:

/* all string.h functions */
struct LibraryFunction StringFunctions[] =
{
#ifndef WIN32
	{StringIndex,   "char *index(char *,int);"},
    {StringRindex,  "char *rindex(char *,int);"},
#endif
    {StringMemcpy,  "void *memcpy(void *,void *,int);"},
    {StringMemmove, "void *memmove(void *,void *,int);"},
    {StringMemchr,  "void *memchr(char *,int,int);"},
    {StringMemcmp,  "int memcmp(void *,void *,int);"},
    {StringMemset,  "void *memset(void *,int,int);"},
    {StringStrcat,  "char *strcat(char *,char *);"},
    {StringStrncat, "char *strncat(char *,char *,int);"},
    {StringStrchr,  "char *strchr(char *,int);"},
    {StringStrrchr, "char *strrchr(char *,int);"},
    {StringStrcmp,  "int strcmp(char *,char *);"},
    {StringStrncmp, "int strncmp(char *,char *,int);"},
    {StringStrcoll, "int strcoll(char *,char *);"},
    {StringStrcpy,  "char *strcpy(char *,char *);"},
    {StringStrncpy, "char *strncpy(char *,char *,int);"},
    {StringStrerror,"char *strerror(int);"},
    {StringStrlen,  "int strlen(char *);"},
    {StringStrspn,  "int strspn(char *,char *);"},
    {StringStrcspn, "int strcspn(char *,char *);"},
    {StringStrpbrk, "char *strpbrk(char *,char *);"},
    {StringStrstr,  "char *strstr(char *,char *);"},
    {StringStrtok,  "char *strtok(char *,char *);"},
    {StringStrxfrm, "int strxfrm(char *,char *,int);"},
	{StringStrdup,  "char *strdup(char *);"},
#ifndef WIN32
    {StringStrtok_r,"char *strtok_r(char *,char *,char **);"},
#endif
    {NULL,          NULL }
};

I thought it might be better if this went directly into the trunk.

operator not expected here

In picoc real numbers are assign with a digit in front dot
ex 90.1 0.4
but fails when real nymbers are assign in a more common way
ex .5
here below an example error :

#include <stdio.h>
int main() 
{
	double a=.5; // <-- operator not expected here

	return 0;
}

switch within a switch fails

Hello Everybody
Following Codesample

switch (Var1)
{
case 0:
// Do Something
break;
case 1:
Var3++;
switch (Var2)
{
case 0:
// Do Something
break;
case 1:
// Do Something
break;
}
break;
}
The Problem is, if Var1 != 1 the second switch statement (Var2) is executed with Var2 always zero.
But, the code ( Var3++) outside of the second switch is not executed !
So, something goes completely wrong here !
Any ideas or fixes ?
Thanks
Manfred

Libc math functions expm1 and log1p needed

Dear Sir,

Please add libc math functions expm1, which is exp(x) - 1, and log1p, which is log(1+x) as both are necessary to compute above two math functions with full precision for small x<<1. Computing exp(x) - 1 from given exp(x) causes loss of precision because exp(x) is close to 1 for small x, and a difference of two quantities both near 1 is involved. Similarly for log(1+x).

Many thanks,

Sanjay Jain

The integer LONG_MIN evaluates to 0

Trying to input the value of LONG_MIN on your platform, you get 0.

picoc> long x;
picoc> x = -9223372036854775808L;
picoc> printf("%ld\n", x);
0

Compiled, that code produces the expected -9223372036854775808.

Define macro inside a function block will crash picoc

void printArray(void) {

define SIZE 10

int array[SIZE] = {5, 4, 3, 9, 1, 8, 6, 7, 5, 2};
printf("4: %d\n", array[4]);
}
printArray();

6907 segmentation fault

The following code will work:

define SIZE 10

void printArray(void) {
int array[SIZE] = {5, 4, 3, 9, 1, 8, 6, 7, 5, 2};
printf("4: %d\n", array[4]);
}
printArray();

Issue copied from: https://code.google.com/p/picoc/issues/detail?id=192 and
https://code.google.com/p/picoc/issues/detail?id=193

how to use breakpoints

Hi, thanks for your excellent project. I can see an example of using the breakpoint functions in debug.c. Are there any example or docs.?Regards

Issue with unsigned variables

The following code:

unsigned crc;
crc = 0x80000000;
crc >>= 1;
printf("crc = %X\n", crc);_

produces the following output:

crc = C0000000

Which is wrong (should be 4000000)

Multiple Heap Buffer Overflows in PicoC at Various Locations

Hi,

I was running my fuzz tests in the background and discovered multiple heap buffer overflows in PicoC Version 3.2.2 at various locations. After triaging all of the crashes, I can verify that there are 10 separate and unique heap buffer overflows at the following locations:

  • StdioBasePrintf in cstdlib/stdio.c when called from ExpressionParseFunctionCall in expression.c
  • LexGetStringConstant in lex.c when called from LexScanGetToken in lex.c
  • ExpressionCoerceUnsignedInteger in expression.c when called from ExpressionParseFunctionCall in expression.c
  • ExpressionCoerceInteger in expression.c when called from ExpressionInfixOperator in expression.c
  • ExpressionAssign in expression.c when called from ExpressionParseMacroCall in expression.c
  • StringStrcat in cstdlib/string.c when called from ExpressionParseFunctionCall in expression.c
  • StringStrncpy in cstdlib/string.c when called from ExpressionParseFunctionCall in expression.c
  • ExpressionCoerceFP in expression.c when called from ExpressionParseFunctionCall in expression.c
  • StdioOutPutc in cstdlib/stdio.c when called from ExpressionParseFunctionCall in expression.c
  • LexSkipComment in lex.c when called from LexScanGetToken in lex.c

Reproduction and Details

For each of the heap buffer overflows I have attached a reproduction file and the full output from ASAN (address sanitizer). The easiest way to reproduce each overflow would be to run the relevant file through the interpreter:

picoc -s [reproduction_filename.c]

StdioBasePrintf in cstdlib/stdio.c when called from ExpressionParseFunctionCall in expression.c.

File for Reprotuction: cstdlib_stdio_heap_overflow.c.zip

=================================================================
==912065==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000563b at pc 0x562a94fe1ae8 bp 0x7ffc0f423270 sp 0x7ffc0f423268
READ of size 1 at 0x60300000563b thread T0
    #0 0x562a94fe1ae7 in StdioBasePrintf cstdlib/stdio.c:249
    #1 0x562a94fe4e9f in StdioPrintf cstdlib/stdio.c:682
    #2 0x562a94fd2edd in ExpressionParseFunctionCall /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1909
    #3 0x562a94fd037c in ExpressionParse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1607
    #4 0x562a94fc46a0 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:646
    #5 0x562a94fc3b07 in ParseBlock /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:558
    #6 0x562a94fc474b in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:651
    #7 0x562a94fc0028 in ParseStatementMaybeRun /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:54
    #8 0x562a94fc49db in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:681
    #9 0x562a94fc6380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #10 0x562a94fded0e in PicocPlatformScanFile platform/platform_unix.c:129
    #11 0x562a94fb5213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #12 0x7fb5e3fe57fc in __libc_start_main ../csu/libc-start.c:332
    #13 0x562a94fb4d49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x60300000563b is located 0 bytes to the right of 27-byte region [0x603000005620,0x60300000563b)
allocated by thread T0 here:
    #0 0x7fb5e43e0987 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x562a94fd3b80 in HeapAllocMem /home/kali/projects/fuzzing/fuzz_targets/picoc/heap.c:127
    #2 0x562a94fb624a in TableSetIdentifier /home/kali/projects/fuzzing/fuzz_targets/picoc/table.c:162
    #3 0x562a94fb645b in TableStrRegister2 /home/kali/projects/fuzzing/fuzz_targets/picoc/table.c:179
    #4 0x562a94fb9965 in LexGetStringConstant /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:390
    #5 0x562a94fbac4f in LexScanGetToken /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:502
    #6 0x562a94fbbfc6 in LexTokenize /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:642
    #7 0x562a94fbc527 in LexAnalyse /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:704
    #8 0x562a94fc61b7 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:874
    #9 0x562a94fded0e in PicocPlatformScanFile platform/platform_unix.c:129
    #10 0x562a94fb5213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #11 0x7fb5e3fe57fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow cstdlib/stdio.c:249 in StdioBasePrintf
Shadow bytes around the buggy address:
  0x0c067fff8a70: fd fd fd fa fa fa 00 00 00 00 fa fa fd fd fd fa
  0x0c067fff8a80: fa fa fd fd fd fa fa fa 00 00 00 00 fa fa fd fd
  0x0c067fff8a90: fd fa fa fa 00 00 00 00 fa fa fd fd fd fa fa fa
  0x0c067fff8aa0: 00 00 00 00 fa fa fd fd fd fa fa fa 00 00 00 00
  0x0c067fff8ab0: fa fa fd fd fd fa fa fa 00 00 00 02 fa fa 00 00
=>0x0c067fff8ac0: 00 02 fa fa 00 00 00[03]fa fa 00 00 00 03 fa fa
  0x0c067fff8ad0: 00 00 00 07 fa fa 00 00 00 02 fa fa 00 00 00 02
  0x0c067fff8ae0: fa fa 00 00 00 05 fa fa 00 00 00 02 fa fa 00 00
  0x0c067fff8af0: 00 fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8b10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912065==ABORTING

LexGetStringConstant in lex.c when called from LexScanGetToken in lex.c.

File for Reprotuction:

LexGetStringConstant_lex_heap_overflow.c.zip

=================================================================
==912099==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60c0000000b5 at pc 0x558299178802 bp 0x7ffcde91cc50 sp 0x7ffcde91cc48
READ of size 1 at 0x60c0000000b5 thread T0
    #0 0x558299178801 in LexGetStringConstant /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:361
    #1 0x558299179c4f in LexScanGetToken /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:502
    #2 0x55829917afc6 in LexTokenize /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:642
    #3 0x55829917b527 in LexAnalyse /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:704
    #4 0x5582991851b7 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:874
    #5 0x55829919dd0e in PicocPlatformScanFile platform/platform_unix.c:129
    #6 0x558299174213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #7 0x7fee5afb97fc in __libc_start_main ../csu/libc-start.c:332
    #8 0x558299173d49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x60c0000000b5 is located 0 bytes to the right of 117-byte region [0x60c000000040,0x60c0000000b5)
allocated by thread T0 here:
    #0 0x7fee5b3b47cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x55829919d8a7 in PlatformReadFile platform/platform_unix.c:94
    #2 0x55829919dbfc in PicocPlatformScanFile platform/platform_unix.c:121
    #3 0x558299174213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #4 0x7fee5afb97fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:361 in LexGetStringConstant
Shadow bytes around the buggy address:
  0x0c187fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff8000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
=>0x0c187fff8010: 00 00 00 00 00 00[05]fa fa fa fa fa fa fa fa fa
  0x0c187fff8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 fa
  0x0c187fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912099==ABORTING

ExpressionCoerceUnsignedInteger in expression.c when called from ExpressionParseFunctionCall in expression.c.

File for Reprotuction:

ExpressionCoerceUnsignedInteger_heap_overflow.c.zip

=================================================================
==912164==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x607000000230 at pc 0x563f0e1b0f72 bp 0x7ffc1ad03030 sp 0x7ffc1ad03028
READ of size 4 at 0x607000000230 thread T0
    #0 0x563f0e1b0f71 in ExpressionCoerceUnsignedInteger /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:270
    #1 0x563f0e1cb451 in StdioBasePrintf cstdlib/stdio.c:379
    #2 0x563f0e1cee9f in StdioPrintf cstdlib/stdio.c:682
    #3 0x563f0e1bcedd in ExpressionParseFunctionCall /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1909
    #4 0x563f0e1ba37c in ExpressionParse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1607
    #5 0x563f0e1ae6a0 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:646
    #6 0x563f0e1ad6c1 in ParseFor /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:524
    #7 0x563f0e1aee02 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:715
    #8 0x563f0e1b0380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #9 0x563f0e1c8d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #10 0x563f0e19f213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #11 0x7f1dbc2477fc in __libc_start_main ../csu/libc-start.c:332
    #12 0x563f0e19ed49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x607000000230 is located 0 bytes to the right of 80-byte region [0x6070000001e0,0x607000000230)
allocated by thread T0 here:
    #0 0x7f1dbc642987 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x563f0e1bdb80 in HeapAllocMem /home/kali/projects/fuzzing/fuzz_targets/picoc/heap.c:127
    #2 0x563f0e1c23a9 in VariableAlloc /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:77
    #3 0x563f0e1c2429 in VariableAllocValueAndData /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:97
    #4 0x563f0e1c2701 in VariableAllocValueFromType /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:119
    #5 0x563f0e1c3aa7 in VariableDefine /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:303
    #6 0x563f0e1c46aa in VariableDefineButIgnoreIdentical /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:383
    #7 0x563f0e1ac540 in ParseDeclaration /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:366
    #8 0x563f0e1aef6e in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:738
    #9 0x563f0e1b0380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #10 0x563f0e1c8d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #11 0x563f0e19f213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #12 0x7f1dbc2477fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:270 in ExpressionCoerceUnsignedInteger
Shadow bytes around the buggy address:
  0x0c0e7fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0e7fff8000: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fa fa
  0x0c0e7fff8010: fa fa fd fd fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0e7fff8020: 00 00 00 00 00 00 00 00 05 fa fa fa fa fa 00 00
  0x0c0e7fff8030: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
=>0x0c0e7fff8040: 00 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0e7fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912164==ABORTING

ExpressionAssign in expression.c when called from ExpressionParseMacroCall in expression.c.

File for Reprotuction:

ExpressionAssign_heap_overflow.c.zip

=================================================================
==912198==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000005608 at pc 0x563053b280cb bp 0x7ffe0502f540 sp 0x7ffe0502f538
READ of size 8 at 0x603000005608 thread T0
    #0 0x563053b280ca in ExpressionAssign /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:516
    #1 0x563053b309ba in ExpressionParseMacroCall /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1781
    #2 0x563053b30d30 in ExpressionParseFunctionCall /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1805
    #3 0x563053b2f37c in ExpressionParse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1607
    #4 0x563053b31253 in ExpressionParseFunctionCall /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1834
    #5 0x563053b2f37c in ExpressionParse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1607
    #6 0x563053b236a0 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:646
    #7 0x563053b25380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #8 0x563053b3dd0e in PicocPlatformScanFile platform/platform_unix.c:129
    #9 0x563053b14213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #10 0x7f94cf72f7fc in __libc_start_main ../csu/libc-start.c:332
    #11 0x563053b13d49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x60300000560f is located 0 bytes to the right of 31-byte region [0x6030000055f0,0x60300000560f)
allocated by thread T0 here:
    #0 0x7f94cfb2a987 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x563053b32b80 in HeapAllocMem /home/kali/projects/fuzzing/fuzz_targets/picoc/heap.c:127
    #2 0x563053b1524a in TableSetIdentifier /home/kali/projects/fuzzing/fuzz_targets/picoc/table.c:162
    #3 0x563053b1545b in TableStrRegister2 /home/kali/projects/fuzzing/fuzz_targets/picoc/table.c:179
    #4 0x563053b17910 in LexGetWord /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:254
    #5 0x563053b199f8 in LexScanGetToken /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:493
    #6 0x563053b1afc6 in LexTokenize /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:642
    #7 0x563053b1b527 in LexAnalyse /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:704
    #8 0x563053b251b7 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:874
    #9 0x563053b3dd0e in PicocPlatformScanFile platform/platform_unix.c:129
    #10 0x563053b14213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #11 0x7f94cf72f7fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:516 in ExpressionAssign
Shadow bytes around the buggy address:
  0x0c067fff8a70: fd fd fd fa fa fa 00 00 00 00 fa fa fd fd fd fa
  0x0c067fff8a80: fa fa fd fd fd fa fa fa 00 00 00 00 fa fa fd fd
  0x0c067fff8a90: fd fa fa fa 00 00 00 00 fa fa fd fd fd fa fa fa
  0x0c067fff8aa0: 00 00 00 00 fa fa fd fd fd fa fa fa 00 00 00 00
  0x0c067fff8ab0: fa fa fd fd fd fa fa fa 00 00 00 05 fa fa 00 00
=>0x0c067fff8ac0: 00[07]fa fa 00 00 00 02 fa fa 00 00 00 04 fa fa
  0x0c067fff8ad0: 00 00 00 05 fa fa 00 00 00 05 fa fa 00 00 00 fa
  0x0c067fff8ae0: fa fa 00 00 00 00 fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8af0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8b10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912198==ABORTING

StringStrcat in cstdlib/string.c L40 when called from ExpressionParseFunctionCall in expression.c.

File for Reprotuction:

StringStrcat_heap_overflow.c.zip

=================================================================
==912341==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x606000000832 at pc 0x7f93cb901590 bp 0x7ffc7cfa1530 sp 0x7ffc7cfa0ce0
WRITE of size 26 at 0x606000000832 thread T0
    #0 0x7f93cb90158f in __interceptor_strcat ../../../../src/libsanitizer/asan/asan_interceptors.cpp:392
    #1 0x561b032f2412 in StringStrcat cstdlib/string.c:40
    #2 0x561b032dbedd in ExpressionParseFunctionCall /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1909
    #3 0x561b032d937c in ExpressionParse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1607
    #4 0x561b032cd6a0 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:646
    #5 0x561b032cf380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #6 0x561b032e7d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #7 0x561b032be213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #8 0x7f93cb57a7fc in __libc_start_main ../csu/libc-start.c:332
    #9 0x561b032bdd49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x606000000832 is located 0 bytes to the right of 50-byte region [0x606000000800,0x606000000832)
allocated by thread T0 here:
    #0 0x7f93cb975987 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x561b032dcb80 in HeapAllocMem /home/kali/projects/fuzzing/fuzz_targets/picoc/heap.c:127
    #2 0x561b032e13a9 in VariableAlloc /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:77
    #3 0x561b032e1429 in VariableAllocValueAndData /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:97
    #4 0x561b032e1701 in VariableAllocValueFromType /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:119
    #5 0x561b032e2aa7 in VariableDefine /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:303
    #6 0x561b032e36aa in VariableDefineButIgnoreIdentical /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:383
    #7 0x561b032cb540 in ParseDeclaration /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:366
    #8 0x561b032cdf6e in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:738
    #9 0x561b032cf380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #10 0x561b032e7d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #11 0x561b032be213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #12 0x7f93cb57a7fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/asan/asan_interceptors.cpp:392 in __interceptor_strcat
Shadow bytes around the buggy address:
  0x0c0c7fff80b0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
  0x0c0c7fff80c0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0c7fff80d0: 00 00 00 00 00 00 06 fa fa fa fa fa 00 00 00 00
  0x0c0c7fff80e0: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 02 fa
  0x0c0c7fff80f0: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa
=>0x0c0c7fff8100: 00 00 00 00 00 00[02]fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8150: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912341==ABORTING

StringStrncpy in cstdlib/string.c L19 when called from ExpressionParseFunctionCall in expression.c.

File for Reprotuction:

StringStrncpy_heap_overflow.c.zip

=================================================================
==912388==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000007d2 at pc 0x7f4683a4db45 bp 0x7fff7dde02e0 sp 0x7fff7dddfa90
WRITE of size 22 at 0x6060000007d2 thread T0
    #0 0x7f4683a4db44 in __interceptor_strncpy ../../../../src/libsanitizer/asan/asan_interceptors.cpp:485
    #1 0x55a9a96daf48 in StringStrncpy cstdlib/string.c:19
    #2 0x55a9a96c4edd in ExpressionParseFunctionCall /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1909
    #3 0x55a9a96c237c in ExpressionParse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1607
    #4 0x55a9a96b66a0 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:646
    #5 0x55a9a96b8380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #6 0x55a9a96d0d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #7 0x55a9a96a7213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #8 0x7f46836a77fc in __libc_start_main ../csu/libc-start.c:332
    #9 0x55a9a96a6d49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x6060000007d2 is located 0 bytes to the right of 50-byte region [0x6060000007a0,0x6060000007d2)
allocated by thread T0 here:
    #0 0x7f4683aa2987 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x55a9a96c5b80 in HeapAllocMem /home/kali/projects/fuzzing/fuzz_targets/picoc/heap.c:127
    #2 0x55a9a96ca3a9 in VariableAlloc /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:77
    #3 0x55a9a96ca429 in VariableAllocValueAndData /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:97
    #4 0x55a9a96ca701 in VariableAllocValueFromType /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:119
    #5 0x55a9a96cbaa7 in VariableDefine /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:303
    #6 0x55a9a96cc6aa in VariableDefineButIgnoreIdentical /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:383
    #7 0x55a9a96b4540 in ParseDeclaration /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:366
    #8 0x55a9a96b6f6e in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:738
    #9 0x55a9a96b8380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #10 0x55a9a96d0d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #11 0x55a9a96a7213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #12 0x7f46836a77fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/asan/asan_interceptors.cpp:485 in __interceptor_strncpy
Shadow bytes around the buggy address:
  0x0c0c7fff80a0: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0c7fff80b0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
  0x0c0c7fff80c0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0c7fff80d0: 00 00 00 00 00 00 06 fa fa fa fa fa 00 00 00 00
  0x0c0c7fff80e0: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 00
=>0x0c0c7fff80f0: fa fa fa fa 00 00 00 00 00 00[02]fa fa fa fa fa
  0x0c0c7fff8100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912388==ABORTING

ExpressionCoerceFP in expression.c when called from ExpressionParseFunctionCall in expression.c.

File for Reprotuction:

ExpressionCoerceFP_heap_overflow.c.zip

=================================================================
==912597==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000adb8 at pc 0x5555f45b9467 bp 0x7ffcd4551690 sp 0x7ffcd4551688
READ of size 1 at 0x60400000adb8 thread T0
    #0 0x5555f45b9466 in ExpressionCoerceFP /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:300
    #1 0x5555f45d35c2 in StdioBasePrintf cstdlib/stdio.c:385
    #2 0x5555f45d6e9f in StdioPrintf cstdlib/stdio.c:682
    #3 0x5555f45c4edd in ExpressionParseFunctionCall /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1909
    #4 0x5555f45c237c in ExpressionParse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1607
    #5 0x5555f45b66a0 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:646
    #6 0x5555f45b56c1 in ParseFor /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:524
    #7 0x5555f45b6e02 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:715
    #8 0x5555f45b8380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #9 0x5555f45d0d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #10 0x5555f45a7213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #11 0x7fa48e4d67fc in __libc_start_main ../csu/libc-start.c:332
    #12 0x5555f45a6d49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x60400000adb8 is located 2 bytes to the right of 38-byte region [0x60400000ad90,0x60400000adb6)
allocated by thread T0 here:
    #0 0x7fa48e8d1987 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x5555f45c5b80 in HeapAllocMem /home/kali/projects/fuzzing/fuzz_targets/picoc/heap.c:127
    #2 0x5555f45a824a in TableSetIdentifier /home/kali/projects/fuzzing/fuzz_targets/picoc/table.c:162
    #3 0x5555f45a845b in TableStrRegister2 /home/kali/projects/fuzzing/fuzz_targets/picoc/table.c:179
    #4 0x5555f45ab965 in LexGetStringConstant /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:390
    #5 0x5555f45acc4f in LexScanGetToken /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:502
    #6 0x5555f45adfc6 in LexTokenize /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:642
    #7 0x5555f45ae527 in LexAnalyse /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:704
    #8 0x5555f45b81b7 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:874
    #9 0x5555f45d0d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #10 0x5555f45a7213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #11 0x7fa48e4d67fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:300 in ExpressionCoerceFP
Shadow bytes around the buggy address:
  0x0c087fff9560: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9570: fa fa 00 00 00 00 01 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9580: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9590: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95a0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
=>0x0c087fff95b0: fa fa 00 00 00 00 06[fa]fa fa 00 00 00 00 00 fa
  0x0c087fff95c0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95d0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95e0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 03 fa
  0x0c087fff95f0: fa fa 00 00 00 00 00 05 fa fa 00 00 00 00 00 fa
  0x0c087fff9600: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912597==ABORTING

StdioOutPutc in cstdlib/stdio.c L64 when called from ExpressionParseFunctionCall in expression.c.

File for Reprotuction:

StdioOutPutc_heap_overflow.c.zip

=================================================================
==912677==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000aef8 at pc 0x55af1d709269 bp 0x7ffd9cb1bf90 sp 0x7ffd9cb1bf88
WRITE of size 1 at 0x60400000aef8 thread T0
    #0 0x55af1d709268 in StdioOutPutc cstdlib/stdio.c:64
    #1 0x55af1d70baa8 in StdioBasePrintf cstdlib/stdio.c:415
    #2 0x55af1d70f768 in StdioSprintf cstdlib/stdio.c:718
    #3 0x55af1d6fcedd in ExpressionParseFunctionCall /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1909
    #4 0x55af1d6fa37c in ExpressionParse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1607
    #5 0x55af1d6ee6a0 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:646
    #6 0x55af1d6edb07 in ParseBlock /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:558
    #7 0x55af1d6ee74b in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:651
    #8 0x55af1d6ea028 in ParseStatementMaybeRun /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:54
    #9 0x55af1d6ed55c in ParseFor /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:504
    #10 0x55af1d6eee02 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:715
    #11 0x55af1d6f0380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #12 0x55af1d708d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #13 0x55af1d6df213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #14 0x7fddae07c7fc in __libc_start_main ../csu/libc-start.c:332
    #15 0x55af1d6ded49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x60400000aef8 is located 0 bytes to the right of 40-byte region [0x60400000aed0,0x60400000aef8)
allocated by thread T0 here:
    #0 0x7fddae477987 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x55af1d6fdb80 in HeapAllocMem /home/kali/projects/fuzzing/fuzz_targets/picoc/heap.c:127
    #2 0x55af1d7023a9 in VariableAlloc /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:77
    #3 0x55af1d702429 in VariableAllocValueAndData /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:97
    #4 0x55af1d702701 in VariableAllocValueFromType /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:119
    #5 0x55af1d703aa7 in VariableDefine /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:303
    #6 0x55af1d7046aa in VariableDefineButIgnoreIdentical /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:383
    #7 0x55af1d6ec540 in ParseDeclaration /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:366
    #8 0x55af1d6eef6e in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:738
    #9 0x55af1d6f0380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #10 0x55af1d708d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #11 0x55af1d6df213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #12 0x7fddae07c7fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow cstdlib/stdio.c:64 in StdioOutPutc
Shadow bytes around the buggy address:
  0x0c087fff9580: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9590: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95a0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95b0: fa fa 00 00 00 00 02 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95c0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
=>0x0c087fff95d0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00[fa]
  0x0c087fff95e0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 00
  0x0c087fff95f0: fa fa 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
  0x0c087fff9600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912677==ABORTING

ExpressionCoerceInteger in expression.c when called from ExpressionInfixOperator in expression.c.

File for Reprotuction:

ExpressionCoerceInteger_heap_overflow.c.zip

=================================================================
==912683==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000007d8 at pc 0x56335c8a2b15 bp 0x7ffe99b322b0 sp 0x7ffe99b322a8
READ of size 4 at 0x6060000007d8 thread T0
    #0 0x56335c8a2b14 in ExpressionCoerceInteger /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:242
    #1 0x56335c8a9028 in ExpressionInfixOperator /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1007
    #2 0x56335c8aa85c in ExpressionStackCollapse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1316
    #3 0x56335c8acc7b in ExpressionParse /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:1684
    #4 0x56335c8a06a0 in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:646
    #5 0x56335c8a2380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #6 0x56335c8bad0e in PicocPlatformScanFile platform/platform_unix.c:129
    #7 0x56335c891213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #8 0x7fefacb2b7fc in __libc_start_main ../csu/libc-start.c:332
    #9 0x56335c890d49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x6060000007d8 is located 0 bytes to the right of 56-byte region [0x6060000007a0,0x6060000007d8)
allocated by thread T0 here:
    #0 0x7fefacf26987 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
    #1 0x56335c8afb80 in HeapAllocMem /home/kali/projects/fuzzing/fuzz_targets/picoc/heap.c:127
    #2 0x56335c8b43a9 in VariableAlloc /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:77
    #3 0x56335c8b4429 in VariableAllocValueAndData /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:97
    #4 0x56335c8b4701 in VariableAllocValueFromType /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:119
    #5 0x56335c8b5aa7 in VariableDefine /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:303
    #6 0x56335c8b66aa in VariableDefineButIgnoreIdentical /home/kali/projects/fuzzing/fuzz_targets/picoc/variable.c:383
    #7 0x56335c89e540 in ParseDeclaration /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:366
    #8 0x56335c8a0f6e in ParseStatement /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:738
    #9 0x56335c8a2380 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:897
    #10 0x56335c8bad0e in PicocPlatformScanFile platform/platform_unix.c:129
    #11 0x56335c891213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #12 0x7fefacb2b7fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kali/projects/fuzzing/fuzz_targets/picoc/expression.c:242 in ExpressionCoerceInteger
Shadow bytes around the buggy address:
  0x0c0c7fff80a0: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0c7fff80b0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
  0x0c0c7fff80c0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0c7fff80d0: 00 00 00 00 00 00 06 fa fa fa fa fa 00 00 00 00
  0x0c0c7fff80e0: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 00
=>0x0c0c7fff80f0: fa fa fa fa 00 00 00 00 00 00 00[fa]fa fa fa fa
  0x0c0c7fff8100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912683==ABORTING

LexSkipComment in lex.c when called from LexScanGetToken in lex.c.

File for Reprotuction:

LexSkipComment_heap_overflow.c.zip

=================================================================
==912887==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60c0000000b9 at pc 0x55736f5b3e90 bp 0x7ffe3e509790 sp 0x7ffe3e509788
READ of size 1 at 0x60c0000000b9 thread T0
    #0 0x55736f5b3e8f in LexSkipComment /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:430
    #1 0x55736f5b521c in LexScanGetToken /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:532
    #2 0x55736f5b5fc6 in LexTokenize /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:642
    #3 0x55736f5b6527 in LexAnalyse /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:704
    #4 0x55736f5c01b7 in PicocParse /home/kali/projects/fuzzing/fuzz_targets/picoc/parse.c:874
    #5 0x55736f5d8d0e in PicocPlatformScanFile platform/platform_unix.c:129
    #6 0x55736f5af213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #7 0x7f22e68a87fc in __libc_start_main ../csu/libc-start.c:332
    #8 0x55736f5aed49 in _start (/home/kali/projects/fuzzing/fuzz_targets/picoc/picoc+0x16d49)

0x60c0000000b9 is located 0 bytes to the right of 121-byte region [0x60c000000040,0x60c0000000b9)
allocated by thread T0 here:
    #0 0x7f22e6ca37cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x55736f5d88a7 in PlatformReadFile platform/platform_unix.c:94
    #2 0x55736f5d8bfc in PicocPlatformScanFile platform/platform_unix.c:121
    #3 0x55736f5af213 in main /home/kali/projects/fuzzing/fuzz_targets/picoc/picoc.c:62
    #4 0x7f22e68a87fc in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/kali/projects/fuzzing/fuzz_targets/picoc/lex.c:430 in LexSkipComment
Shadow bytes around the buggy address:
  0x0c187fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c187fff8000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
=>0x0c187fff8010: 00 00 00 00 00 00 00[01]fa fa fa fa fa fa fa fa
  0x0c187fff8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05
  0x0c187fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==912887==ABORTING

can't set char*[] from char ** in argument 2 of call to main()

picoc error

startup: can't set char*[] from char ** in argument 2 of call to main()

interpreter fail to recognize in input source file array of pointer to char,
works indeed with pointer to pointer to char

file to input :

int main(int argc, char *argv[])

error !?

int main(int argc, char **argv)

adjust source file in this way interpreter works perfeclty !

sizeof operator

The operand of a sizeof operator should not be evaluated and should only be used to determine the type of the expression.

The following snippet fails with error "NULL pointer dereference":

struct Point {int x; int y;}
struct Point _myPoint = malloc(sizeof(_myPoint));

PICOC Null Pointer Dereference Denial of Service

PICOC Suffers from a Denial of Service (CWE476) vulnerability as a result of a Null Pointer Dereference. Any project or library that uses Picoc also suffers from this issue. An example of this would be picoc-js (https://www.npmjs.com/package/picoc-js). As a result PICOC will immediately segfault.

Reproduction Steps

  1. Create a file to be executed by the PICOC interpreter
$ touch vulncode
  1. Add the following code to the file:
printf("Before Crash\n");
**4%;
printf("This code won't execute because of the crash\n");

  1. Execute PICOC against the file:
$ ./picoc -s vulncode
  1. You will receive a segfault and the program will crash. This is a result of a null pointer dereference that is not caught or handled by the interpreter. The vulnerable line of code can be seen below:
**4%;

Solution

Adding a few if statements that verify the pointer is not NULL before usage will solve this problem. You can find more information about this here:

https://owasp.org/www-community/vulnerabilities/Null_Dereference

Can’t comment

I can’t comment in picoc with // or /*. Why would this be?

Thank you

Memory leak when parsing Array Initializers

The function ParseArrayInitializer first estimates the number of elements by calling itself again with DoAssignment=False. The problem in line 285. The ExpressionParser allocates the value on the stack.

picoc/parse.c

Line 285 in a97d94f

if (!ExpressionParse(Parser, &CValue))

As DoAssignment is false line 288 is not true and the variable is never released anymore.

I think the following pop condition below shall be added.

if (Parser->Mode == RunModeRun && DoAssignment) { ExpressionAssign(Parser, ArrayElement, CValue, false, NULL, 0, false); VariableStackPop(Parser, CValue); VariableStackPop(Parser, ArrayElement); } else if(Parser->Mode == RunModeRun) { VariableStackPop(Parser, CValue); }

bad type declaration about function pointer

i am trying to execute somes examples this gives me error

following files ( 42_function_:pointer.c ) : bad type declaration

#include <stdio.h>

int fred(int p)
{
	printf("yo %d\n", p);
	return 42;
}

int (*f)(int) = &fred; <-- ERROR

int main()
{
	printf("%d\n", &fred);
	return 0;
}

compiled with mingw32 , window10 , in qt5.10

Multiple bugs found in picoc 3.2.2

Hi, developers of picoc:
In the test of the binary picoc instrumented with ASAN, I found mulitple SEGV/heap-buffer-overflow/FPE/stack-overflow vulnerability in picoc, the version is 3.2.2, commit a97d94f which is also the master branch.

Here are the lists of the crashes:

  • SEGV on unknown address in ExpressionInfixOperator in expression.c:1004
  • heap-buffer-overflow in LexGetCharacterConstant in lex.c:416
  • SEGV on unknown address in TypeGetMatching in type.c:56
  • heap-buffer-overflow in TableSearchIdentifier in table.c:141
  • SEGV on unknown address in ExpressionGetStructElement in expression.c:1397
  • heap-buffer-overflow in StringStrcpy in cstdlib/string.c:12
  • heap-buffer-overflow in LexSkipComment in lex.c:441
  • heap-buffer-overflow in LexScanGetToken in lex.c:472
  • SEGV on unknown address in ExpressionPrefixOperator in expression.c:727
  • SEGV on unknown address in ExpressionInfixOperator in expression.c:932 (also line 933 can lead to SEGV)
  • FPE on unknown address in ExpressionInfixOperator in expression.c:1105
  • FPE on unknown address in ExpressionInfixOperator in expression.c:1026
  • stack-overflow in ParserCopy in parse.c:455
  • SEGV on unknown address in StringStrcmp in cstdlib/string.c:26
  • heap-buffer-overflow in ExpressionCoerceInteger in expression.c:244

ASAN output

input: ExpressionInfixOperator_2

AddressSanitizer:DEADLYSIGNAL
=================================================================
==29353==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000527bcc bp 0x7ffdbc8390f0 sp 0x7ffdbc838f80 T0)
==29353==The signal is caused by a READ memory access.
==29353==Hint: address points to the zero page.
    #0 0x527bcc in ExpressionInfixOperator /home/ferry/hwz/zeroday/picoc/expression.c:1004:50
    #1 0x527bcc in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1316:25
    #2 0x522c7e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1684:5
    #3 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #4 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #5 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #6 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #7 0x7f2045d4283f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #8 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/expression.c:1004:50 in ExpressionInfixOperator
==29353==ABORTING

input: LexGetCharacterConstant

=================================================================
==16136==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000adb1 at pc 0x0000004fe989 bp 0x7ffd3f8f48f0 sp 0x7ffd3f8f48e8
READ of size 1 at 0x60400000adb1 thread T0
    #0 0x4fe988 in LexGetCharacterConstant /home/ferry/hwz/zeroday/picoc/lex.c:416:37
    #1 0x4fe988 in LexScanGetToken /home/ferry/hwz/zeroday/picoc/lex.c:505:24
    #2 0x4fe988 in LexTokenize /home/ferry/hwz/zeroday/picoc/lex.c:642:17
    #3 0x4fe988 in LexAnalyse /home/ferry/hwz/zeroday/picoc/lex.c:704:12
    #4 0x511a1d in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:874:20
    #5 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #6 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #7 0x7f379572983f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #8 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

0x60400000adb1 is located 0 bytes to the right of 33-byte region [0x60400000ad90,0x60400000adb1)
allocated by thread T0 here:
    #0 0x4b0302 in malloc /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145
    #1 0x5623bc in PlatformReadFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:94:16
    #2 0x56294d in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:121:23
    #3 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #4 0x7f379572983f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ferry/hwz/zeroday/picoc/lex.c:416:37 in LexGetCharacterConstant
Shadow bytes around the buggy address:
  0x0c087fff9560: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9570: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9580: fa fa 00 00 00 00 01 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9590: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95a0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
=>0x0c087fff95b0: fa fa 00 00 00 00[01]fa fa fa fa fa fa fa fa fa
  0x0c087fff95c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff95d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff95e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff95f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==16136==ABORTING

input: TypeGetMatching

AddressSanitizer:DEADLYSIGNAL
=================================================================
==16782==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000020 (pc 0x000000545a43 bp 0x7ffd8ef99940 sp 0x7ffd8ef998f0 T0)
==16782==The signal is caused by a READ memory access.
==16782==Hint: address points to the zero page.
    #0 0x545a43 in TypeGetMatching /home/ferry/hwz/zeroday/picoc/type.c:56:46
    #1 0x526076 in ExpressionPrefixOperator /home/ferry/hwz/zeroday/picoc/expression.c:676:21
    #2 0x526076 in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1257:21
    #3 0x522c7e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1684:5
    #4 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #5 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #6 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #7 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #8 0x7f9a5b15f83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #9 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/type.c:56:46 in TypeGetMatching
==16782==ABORTING

input: TableSearchIdentifier

=================================================================
==28653==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000036 at pc 0x0000004f6284 bp 0x7ffd870251e0 sp 0x7ffd870251d8
READ of size 1 at 0x603000000036 thread T0
    #0 0x4f6283 in TableSearchIdentifier /home/ferry/hwz/zeroday/picoc/table.c:141:17
    #1 0x4f6283 in TableSetIdentifier /home/ferry/hwz/zeroday/picoc/table.c:154:37
    #2 0x50518a in LexGetStringConstant /home/ferry/hwz/zeroday/picoc/lex.c:390:17
    #3 0x4fb61c in LexScanGetToken /home/ferry/hwz/zeroday/picoc/lex.c:502:24
    #4 0x4fb61c in LexTokenize /home/ferry/hwz/zeroday/picoc/lex.c:642:17
    #5 0x4fb61c in LexAnalyse /home/ferry/hwz/zeroday/picoc/lex.c:704:12
    #6 0x511a1d in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:874:20
    #7 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #8 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #9 0x7fc725c1f83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #10 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

0x603000000036 is located 10 bytes to the left of 32-byte region [0x603000000040,0x603000000060)
allocated by thread T0 here:
    #0 0x4b04ba in calloc /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:154
    #1 0x4f6295 in TableSetIdentifier /home/ferry/hwz/zeroday/picoc/table.c:162:39
    #2 0x4f6d49 in LexInit /home/ferry/hwz/zeroday/picoc/lex.c:112:13
    #3 0x55bb63 in PicocInitialize /home/ferry/hwz/zeroday/picoc/platform.c:27:5
    #4 0x4f3a7c in main /home/ferry/hwz/zeroday/picoc/picoc.c:44:5
    #5 0x7fc725c1f83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ferry/hwz/zeroday/picoc/table.c:141:17 in TableSearchIdentifier
Shadow bytes around the buggy address:
  0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00 00 01[fa]fa 00 00 00 00 fa fa 00 00
  0x0c067fff8010: 00 06 fa fa 00 00 00 07 fa fa 00 00 00 04 fa fa
  0x0c067fff8020: 00 00 00 07 fa fa 00 00 00 00 fa fa 00 00 00 05
  0x0c067fff8030: fa fa 00 00 00 06 fa fa 00 00 00 05 fa fa 00 00
  0x0c067fff8040: 00 05 fa fa 00 00 00 00 fa fa 00 00 00 07 fa fa
  0x0c067fff8050: 00 00 00 03 fa fa 00 00 00 07 fa fa 00 00 00 05
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==28653==ABORTING

input: ExpressionGetStructElement

AddressSanitizer:DEADLYSIGNAL
=================================================================
==5395==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000051cd98 bp 0x7ffec6f09db0 sp 0x7ffec6f09c40 T0)
==5395==The signal is caused by a READ memory access.
==5395==Hint: address points to the zero page.
    #0 0x51cd98 in ExpressionGetStructElement /home/ferry/hwz/zeroday/picoc/expression.c:1397:25
    #1 0x52011c in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1562:25
    #2 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #3 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #4 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #5 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #6 0x7fa18758e83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #7 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/expression.c:1397:25 in ExpressionGetStructElement
==5395==ABORTING

input: strcpy

=================================================================
==24725==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000aeb8 at pc 0x000000449ef7 bp 0x7ffc9f6121f0 sp 0x7ffc9f6119a0
WRITE of size 6 at 0x60400000aeb8 thread T0
    #0 0x449ef6 in strcpy /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:438
    #1 0x579c51 in StringStrcpy /home/ferry/hwz/zeroday/picoc/cstdlib/string.c:12:33
    #2 0x520084 in ExpressionParseFunctionCall /home/ferry/hwz/zeroday/picoc/expression.c:1909:13
    #3 0x520084 in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1607:17
    #4 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #5 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #6 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #7 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #8 0x7f12dd6bd83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #9 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

0x60400000aeb8 is located 0 bytes to the right of 40-byte region [0x60400000ae90,0x60400000aeb8)
allocated by thread T0 here:
    #0 0x4b04ba in calloc /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:154
    #1 0x5535a8 in VariableAlloc /home/ferry/hwz/zeroday/picoc/variable.c:77:20
    #2 0x5535a8 in VariableAllocValueAndData /home/ferry/hwz/zeroday/picoc/variable.c:97:30
    #3 0x5535a8 in VariableAllocValueFromType /home/ferry/hwz/zeroday/picoc/variable.c:119:30
    #4 0x557cee in VariableDefine /home/ferry/hwz/zeroday/picoc/variable.c:303:23
    #5 0x557cee in VariableDefineButIgnoreIdentical /home/ferry/hwz/zeroday/picoc/variable.c:383:20
    #6 0x510a41 in ParseDeclaration /home/ferry/hwz/zeroday/picoc/parse.c:366:35
    #7 0x50936a in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:738:34
    #8 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #9 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #10 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #11 0x7f12dd6bd83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_interceptors.cpp:438 in strcpy
Shadow bytes around the buggy address:
  0x0c087fff9580: fa fa 00 00 00 00 01 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9590: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95a0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95b0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95c0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
=>0x0c087fff95d0: fa fa 00 00 00 00 00[fa]fa fa 00 00 00 00 00 fa
  0x0c087fff95e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff95f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==24725==ABORTING

input: LexSkipComment

=================================================================
==12771==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6030000055d7 at pc 0x0000004fdf21 bp 0x7fff642154f0 sp 0x7fff642154e8
READ of size 1 at 0x6030000055d7 thread T0
    #0 0x4fdf20 in LexSkipComment /home/ferry/hwz/zeroday/picoc/lex.c:441:44
    #1 0x4fdf20 in LexScanGetToken /home/ferry/hwz/zeroday/picoc/lex.c:532:17
    #2 0x4fdf20 in LexTokenize /home/ferry/hwz/zeroday/picoc/lex.c:642:17
    #3 0x4fdf20 in LexAnalyse /home/ferry/hwz/zeroday/picoc/lex.c:704:12
    #4 0x511a1d in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:874:20
    #5 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #6 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #7 0x7f32a94a283f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #8 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

0x6030000055d7 is located 0 bytes to the right of 23-byte region [0x6030000055c0,0x6030000055d7)
allocated by thread T0 here:
    #0 0x4b0302 in malloc /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145
    #1 0x5623bc in PlatformReadFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:94:16
    #2 0x56294d in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:121:23
    #3 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #4 0x7f32a94a283f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ferry/hwz/zeroday/picoc/lex.c:441:44 in LexSkipComment
Shadow bytes around the buggy address:
  0x0c067fff8a60: 00 00 fa fa fd fd fd fa fa fa 00 00 00 00 fa fa
  0x0c067fff8a70: fd fd fd fa fa fa 00 00 00 00 fa fa fd fd fd fa
  0x0c067fff8a80: fa fa fd fd fd fa fa fa 00 00 00 00 fa fa fd fd
  0x0c067fff8a90: fd fa fa fa 00 00 00 00 fa fa fd fd fd fa fa fa
  0x0c067fff8aa0: 00 00 00 00 fa fa fd fd fd fa fa fa 00 00 00 00
=>0x0c067fff8ab0: fa fa fd fd fd fa fa fa 00 00[07]fa fa fa fa fa
  0x0c067fff8ac0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8ad0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8ae0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8af0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==12771==ABORTING

input: LexScanGetToken

=================================================================
==4136==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000adb6 at pc 0x0000004fdf84 bp 0x7ffd95bfbb30 sp 0x7ffd95bfbb28
READ of size 1 at 0x60400000adb6 thread T0
    #0 0x4fdf83 in LexScanGetToken /home/ferry/hwz/zeroday/picoc/lex.c:472:44
    #1 0x4fdf83 in LexTokenize /home/ferry/hwz/zeroday/picoc/lex.c:642:17
    #2 0x4fdf83 in LexAnalyse /home/ferry/hwz/zeroday/picoc/lex.c:704:12
    #3 0x511a1d in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:874:20
    #4 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #5 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #6 0x7ff147c6683f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #7 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

0x60400000adb6 is located 0 bytes to the right of 38-byte region [0x60400000ad90,0x60400000adb6)
allocated by thread T0 here:
    #0 0x4b0302 in malloc /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145
    #1 0x5623bc in PlatformReadFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:94:16
    #2 0x56294d in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:121:23
    #3 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #4 0x7ff147c6683f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ferry/hwz/zeroday/picoc/lex.c:472:44 in LexScanGetToken
Shadow bytes around the buggy address:
  0x0c087fff9560: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9570: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9580: fa fa 00 00 00 00 01 fa fa fa 00 00 00 00 00 fa
  0x0c087fff9590: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c087fff95a0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
=>0x0c087fff95b0: fa fa 00 00 00 00[06]fa fa fa fa fa fa fa fa fa
  0x0c087fff95c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff95d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff95e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff95f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c087fff9600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==4136==ABORTING

input : ExpressionPrefixOperator_2

AddressSanitizer:DEADLYSIGNAL
=================================================================
==8154==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000527428 bp 0x7ffd59fceff0 sp 0x7ffd59fcee80 T0)
==8154==The signal is caused by a READ memory access.
==8154==Hint: address points to the zero page.
    #0 0x527428 in ExpressionPrefixOperator /home/ferry/hwz/zeroday/picoc/expression.c:727:20
    #1 0x527428 in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1257:21
    #2 0x522c7e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1684:5
    #3 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #4 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #5 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #6 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #7 0x7f10b680a83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #8 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/expression.c:727:20 in ExpressionPrefixOperator
==8154==ABORTING

input: ExpressionInfixOperator_3

AddressSanitizer:DEADLYSIGNAL
=================================================================
==12218==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000052869f bp 0x7fffe56cd350 sp 0x7fffe56cd1e0 T0)
==12218==The signal is caused by a READ memory access.
==12218==Hint: address points to the zero page.
    #0 0x52869f in ExpressionInfixOperator /home/ferry/hwz/zeroday/picoc/expression.c:932:24
    #1 0x52869f in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1316:25
    #2 0x51ea46 in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1556:78
    #3 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #4 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #5 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #6 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #7 0x7f772bb8283f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #8 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/expression.c:932:24 in ExpressionInfixOperator
==12218==ABORTING

input: ExpressionInfixOperator_FPE_1

AddressSanitizer:DEADLYSIGNAL
=================================================================
==7966==ERROR: AddressSanitizer: FPE on unknown address 0x000000532e59 (pc 0x000000532e59 bp 0x7ffd10cb6930 sp 0x7ffd10cb67c0 T0)
    #0 0x532e59 in ExpressionInfixOperator /home/ferry/hwz/zeroday/picoc/expression.c:1105:35
    #1 0x532e59 in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1316:25
    #2 0x522c7e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1684:5
    #3 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #4 0x50ac80 in ParseFor /home/ferry/hwz/zeroday/picoc/parse.c:485:9
    #5 0x50ac80 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:715:9
    #6 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #7 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #8 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #9 0x7f035833a83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #10 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE /home/ferry/hwz/zeroday/picoc/expression.c:1105:35 in ExpressionInfixOperator
==7966==ABORTING

input: ExpressionInfixOperator_FPE_2

AddressSanitizer:DEADLYSIGNAL
=================================================================
==27557==ERROR: AddressSanitizer: FPE on unknown address 0x000000531f71 (pc 0x000000531f71 bp 0x7ffe058e05b0 sp 0x7ffe058e0440 T0)
    #0 0x531f71 in ExpressionInfixOperator /home/ferry/hwz/zeroday/picoc/expression.c:1026:26
    #1 0x531f71 in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1316:25
    #2 0x522c7e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1684:5
    #3 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #4 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #5 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #6 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #7 0x7fc68240583f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #8 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE /home/ferry/hwz/zeroday/picoc/expression.c:1026:26 in ExpressionInfixOperator
==27557==ABORTING

input: ParserCopy

AddressSanitizer:DEADLYSIGNAL
=================================================================
==31403==ERROR: AddressSanitizer: stack-overflow on address 0x7fff2ac14fb8 (pc 0x0000004aefde bp 0x7fff2ac15820 sp 0x7fff2ac14fc0 T0)
    #0 0x4aefde in __asan_memcpy /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22
    #1 0x508b35 in ParserCopy /home/ferry/hwz/zeroday/picoc/parse.c:455:5
    #2 0x54a6ba in TypeParseFront /home/ferry/hwz/zeroday/picoc/type.c:408:5
... (Omit many contents)
SUMMARY: AddressSanitizer: stack-overflow /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22 in __asan_memcpy
==31403==ABORTING

input: strcmp

hello
char *s
AddressSanitizer:DEADLYSIGNAL
=================================================================
==24145==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000489390 bp 0x7fff2568bf70 sp 0x7fff2568b700 T0)
==24145==The signal is caused by a READ memory access.
==24145==Hint: address points to the zero page.
    #0 0x489390 in __interceptor_strcmp.part.66 /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:448
    #1 0x57a351 in StringStrcmp /home/ferry/hwz/zeroday/picoc/cstdlib/string.c:26:33
    #2 0x520084 in ExpressionParseFunctionCall /home/ferry/hwz/zeroday/picoc/expression.c:1909:13
    #3 0x520084 in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1607:17
    #4 0x5209ef in ExpressionParseFunctionCall /home/ferry/hwz/zeroday/picoc/expression.c:1834:13
    #5 0x5209ef in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1607:17
    #6 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #7 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #8 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #9 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #10 0x7f3c6769c83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #11 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:448 in __interceptor_strcmp.part.66
==24145==ABORTING

input: ExpressionCoerceInteger

=================================================================
==15829==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000005672 at pc 0x00000051b4fd bp 0x7ffe0cda9f90 sp 0x7ffe0cda9f88
READ of size 1 at 0x603000005672 thread T0
    #0 0x51b4fc in ExpressionCoerceInteger /home/ferry/hwz/zeroday/picoc/expression.c:244:32
    #1 0x51b4fc in ExpressionAssignToPointer /home/ferry/hwz/zeroday/picoc/expression.c:492:13
    #2 0x51b4fc in ExpressionAssign /home/ferry/hwz/zeroday/picoc/expression.c:555:9
    #3 0x520b8c in ExpressionParseFunctionCall /home/ferry/hwz/zeroday/picoc/expression.c:1837:21
    #4 0x520b8c in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1607:17
    #5 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #6 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #7 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #8 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #9 0x7f9f6d1aa83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #10 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

0x603000005672 is located 2 bytes to the right of 32-byte region [0x603000005650,0x603000005670)
allocated by thread T0 here:
    #0 0x4b04ba in calloc /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:154
    #1 0x4f6295 in TableSetIdentifier /home/ferry/hwz/zeroday/picoc/table.c:162:39
    #2 0x50518a in LexGetStringConstant /home/ferry/hwz/zeroday/picoc/lex.c:390:17
    #3 0x4fb61c in LexScanGetToken /home/ferry/hwz/zeroday/picoc/lex.c:502:24
    #4 0x4fb61c in LexTokenize /home/ferry/hwz/zeroday/picoc/lex.c:642:17
    #5 0x4fb61c in LexAnalyse /home/ferry/hwz/zeroday/picoc/lex.c:704:12
    #6 0x511a1d in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:874:20
    #7 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #8 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #9 0x7f9f6d1aa83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ferry/hwz/zeroday/picoc/expression.c:244:32 in ExpressionCoerceInteger
Shadow bytes around the buggy address:
  0x0c067fff8a70: fd fd fd fa fa fa 00 00 00 00 fa fa fd fd fd fa
  0x0c067fff8a80: fa fa fd fd fd fa fa fa 00 00 00 00 fa fa fd fd
  0x0c067fff8a90: fd fa fa fa 00 00 00 00 fa fa fd fd fd fa fa fa
  0x0c067fff8aa0: 00 00 00 00 fa fa fd fd fd fa fa fa 00 00 00 00
  0x0c067fff8ab0: fa fa fd fd fd fa fa fa 00 00 00 02 fa fa 00 00
=>0x0c067fff8ac0: 00 06 fa fa 00 00 00 06 fa fa 00 00 00 00[fa]fa
  0x0c067fff8ad0: 00 00 00 04 fa fa 00 00 00 03 fa fa 00 00 00 06
  0x0c067fff8ae0: fa fa 00 00 00 07 fa fa 00 00 00 00 fa fa 00 00
  0x0c067fff8af0: 00 00 fa fa 00 00 00 02 fa fa 00 00 00 05 fa fa
  0x0c067fff8b00: 00 00 00 04 fa fa 00 00 00 04 fa fa 00 00 00 03
  0x0c067fff8b10: fa fa 00 00 00 00 fa fa 00 00 00 04 fa fa 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==15829==ABORTING

Crash input

https://github.com/17ssDP/fuzzer_crashes/tree/main/picoc

Validation steps

git clone https://github.com/jpoirier/picoc.git
cd picoc/
CC=clang CXX=clang++ CFLAGS="$CFLAGS -fsanitize=address -fno-omit-frame-pointer" CXXFLAGS="$CXXFLAGS -fsanitize=address -fno-omit-frame-pointer" make
./picoc -s input

Environment

Ubuntu 16.04
Clang 10.0.1
gcc 5.5

Installation

Hey,

I couldn’t see any information on how to install this tool. After cloning, does it need to have a build script run or the path exported or something?

Thank you

typedef int BOOL; requires semicolon before main ()

#include <stdio.h>

#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS	0
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE	255
#endif

typedef int		BOOL;
#ifndef TRUE
#define TRUE	1
#endif
#ifndef FALSE
#define FALSE	0
#endif

BOOL wait_for_input (void)
{
	char 	c [32];

	printf ("Press any key to continue... ");
	fgets (c, 2, stdin);
	return TRUE;
}

int main (int argc, char **argv)
{
	puts("Hello");
	wait_for_input ();
	return EXIT_SUCCESS;
}

This leads to:
int main (int argc, char **argv)
^
./test.c:29:0 ';' expected

A semicolon inserted as suggested :-)

#include <stdio.h>

#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS	0
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE	255
#endif

typedef int		BOOL;
#ifndef TRUE
#define TRUE	1
#endif
#ifndef FALSE
#define FALSE	0
#endif

BOOL wait_for_input (void)
{
	char 	c [32];

	printf ("Press any key to continue... ");
	fgets (c, 2, stdin);
	return TRUE;
}

;

int main (int argc, char **argv)
{
	puts("Hello");
	wait_for_input ();
	return EXIT_SUCCESS;
}

This runs the script without error. However, I don't think that semicolon is in the right place there.
OS is Windows and MSVC 2015 here.

Multiple SEGV vulnerabilities found in picoc

Hi, developers of picoc:
In the test of the binary picoc instrumented with ASAN, I found mulitple SEGV vulnerability in picoc, the version is 3.2.2, commit a97d94f which is also the master branch.

Here are the lists of the crashes:

  • SEGV on unknown address in VariableDereferencePointer in variable.c:519
  • SEGV on unknown address in ExpressionPrefixOperator in expression.c:701
  • SEGV on unknown address in ExpressionParse in expression.c:1567
  • SEGV on unknown address in ParseFunctionDefinition in parse.c:124
  • SEGV on unknown address in TypeSizeValue in type.c:103
  • SEGV on unknown address in ExpressionInfixOperator in expression.c:1115
  • SEGV on unknown address in ExpressionParseInt in expression.c:1929
  • SEGV on unknown address in PlatformVPrintf in platform.c:229

ASAN output

AddressSanitizer:DEADLYSIGNAL
=================================================================
==23436==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000055a354 bp 0x7ffc725bbaf0 sp 0x7ffc725bbaf0 T0)
==23436==The signal is caused by a READ memory access.
==23436==Hint: address points to the zero page.
    #0 0x55a354 in VariableDereferencePointer /home/ferry/hwz/zeroday/picoc/variable.c:519:36
    #1 0x527534 in ExpressionStackPushDereference /home/ferry/hwz/zeroday/picoc/expression.c:430:26
    #2 0x527534 in ExpressionPrefixOperator /home/ferry/hwz/zeroday/picoc/expression.c:687:13
    #3 0x527534 in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1257:21
    #4 0x522c7e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1684:5
    #5 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #6 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #7 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #8 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #9 0x7f16c8b4983f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #10 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/variable.c:519:36 in VariableDereferencePointer
==23436==ABORTING
AddressSanitizer:DEADLYSIGNAL
=================================================================
==32224==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000527386 bp 0x7fffe93da9b0 sp 0x7fffe93da840 T0)
==32224==The signal is caused by a READ memory access.
==32224==Hint: address points to the zero page.
    #0 0x527386 in ExpressionPrefixOperator /home/ferry/hwz/zeroday/picoc/expression.c:701:39
    #1 0x527386 in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1257:21
    #2 0x522c7e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1684:5
    #3 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #4 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #5 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #6 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #7 0x7f976071c83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #8 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/expression.c:701:39 in ExpressionPrefixOperator
==32224==ABORTING
AddressSanitizer:DEADLYSIGNAL
=================================================================
==5362==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000052028c bp 0x7ffe08840cb0 sp 0x7ffe08840840 T0)
==5362==The signal is caused by a READ memory access.
==5362==Hint: address points to the zero page.
    #0 0x52028c in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1567:33
    #1 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #2 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #3 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #4 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #5 0x7f31e126c83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #6 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/expression.c:1567:33 in ExpressionParse
==5362==ABORTING
AddressSanitizer:DEADLYSIGNAL
=================================================================
==25931==ERROR: AddressSanitizer: SEGV on unknown address 0x00000000004b (pc 0x000000507511 bp 0x7fff304a8110 sp 0x7fff304a7ee0 T0)
==25931==The signal is caused by a READ memory access.
==25931==Hint: address points to the zero page.
    #0 0x507511 in ParseFunctionDefinition /home/ferry/hwz/zeroday/picoc/parse.c:124:33
    #1 0x51102a in ParseDeclaration /home/ferry/hwz/zeroday/picoc/parse.c:359:17
    #2 0x50936a in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:738:34
    #3 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #4 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #5 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #6 0x7fba8d1af83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #7 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/parse.c:124:33 in ParseFunctionDefinition
==25931==ABORTING
AddressSanitizer:DEADLYSIGNAL
=================================================================
==9790==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000546850 bp 0x7ffe3dd8d430 sp 0x7ffe3dd8d430 T0)
==9790==The signal is caused by a READ memory access.
==9790==Hint: address points to the zero page.
    #0 0x546850 in TypeSizeValue /home/ferry/hwz/zeroday/picoc/type.c:103:9
    #1 0x553d14 in VariableAllocValueAndCopy /home/ferry/hwz/zeroday/picoc/variable.c:132:20
    #2 0x52a533 in ExpressionStackPushValue /home/ferry/hwz/zeroday/picoc/expression.c:409:30
    #3 0x52a533 in ExpressionQuestionMarkOperator /home/ferry/hwz/zeroday/picoc/expression.c:636:9
    #4 0x52a533 in ExpressionInfixOperator /home/ferry/hwz/zeroday/picoc/expression.c:926:9
    #5 0x52a533 in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1316:25
    #6 0x522c7e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1684:5
    #7 0x510bf2 in ParseDeclarationAssignment /home/ferry/hwz/zeroday/picoc/parse.c:326:14
    #8 0x510bf2 in ParseDeclaration /home/ferry/hwz/zeroday/picoc/parse.c:372:21
    #9 0x50936a in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:738:34
    #10 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #11 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #12 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #13 0x7f439f50783f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #14 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/type.c:103:9 in TypeSizeValue
==9790==ABORTING
AddressSanitizer:DEADLYSIGNAL
=================================================================
==21133==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000005283d8 bp 0x7ffcb74f1af0 sp 0x7ffcb74f1980 T0)
==21133==The signal is caused by a READ memory access.
==21133==Hint: address points to the zero page.
    #0 0x5283d8 in ExpressionInfixOperator /home/ferry/hwz/zeroday/picoc/expression.c:1115:39
    #1 0x5283d8 in ExpressionStackCollapse /home/ferry/hwz/zeroday/picoc/expression.c:1316:25
    #2 0x522c7e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1684:5
    #3 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #4 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #5 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #6 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #7 0x7f5f6aeda83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #8 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/expression.c:1115:39 in ExpressionInfixOperator
==21133==ABORTING
AddressSanitizer:DEADLYSIGNAL
=================================================================
==9169==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000005420c8 bp 0x7fffcde07750 sp 0x7fffcde076a0 T0)
==9169==The signal is caused by a READ memory access.
==9169==Hint: address points to the zero page.
    #0 0x5420c8 in ExpressionParseInt /home/ferry/hwz/zeroday/picoc/expression.c:1929:14
    #1 0x5506ec in TypeParseBack /home/ferry/hwz/zeroday/picoc/type.c:507:25
    #2 0x54f8d9 in TypeParseIdentPart /home/ferry/hwz/zeroday/picoc/type.c:574:16
    #3 0x5107a4 in ParseDeclaration /home/ferry/hwz/zeroday/picoc/parse.c:349:9
    #4 0x50936a in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:738:34
    #5 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #6 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #7 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #8 0x7fd163dd683f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #9 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/ferry/hwz/zeroday/picoc/expression.c:1929:14 in ExpressionParseInt
==9169==ABORTING
AddressSanitizer:DEADLYSIGNAL
=================================================================
==8967==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fcff44b67c6 bp 0x7ffe273da700 sp 0x7ffe273d9e98 T0)
==8967==The signal is caused by a READ memory access.
==8967==Hint: address points to the zero page.
    #0 0x7fcff44b67c6 in strlen /build/glibc-S7Ft5T/glibc-2.23/string/../sysdeps/x86_64/strlen.S:106
    #1 0x47bf66 in fputs /home/ferry/Documents/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1255
    #2 0x55dd4a in PlatformVPrintf /home/ferry/hwz/zeroday/picoc/platform.c:229:17
    #3 0x55cc3a in ProgramFail /home/ferry/hwz/zeroday/picoc/platform.c:154:5
    #4 0x51f42e in ExpressionParse /home/ferry/hwz/zeroday/picoc/expression.c:1614:21
    #5 0x50e000 in ParseStatement /home/ferry/hwz/zeroday/picoc/parse.c:646:9
    #6 0x511ba4 in PicocParse /home/ferry/hwz/zeroday/picoc/parse.c:897:14
    #7 0x562ac6 in PicocPlatformScanFile /home/ferry/hwz/zeroday/picoc/platform/platform_unix.c:129:5
    #8 0x4f406a in main /home/ferry/hwz/zeroday/picoc/picoc.c:62:13
    #9 0x7fcff444b83f in __libc_start_main /build/glibc-S7Ft5T/glibc-2.23/csu/../csu/libc-start.c:291
    #10 0x41cf08 in _start (/home/ferry/hwz/zeroday/bin/picoc-asan/picoc+0x41cf08)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /build/glibc-S7Ft5T/glibc-2.23/string/../sysdeps/x86_64/strlen.S:106 in strlen
==8967==ABORTING

Crash input

https://github.com/17ssDP/fuzzer_crashes/tree/main/picoc

Validation steps

git clone https://github.com/jpoirier/picoc.git
cd picoc/
CC=clang CXX=clang++ CFLAGS="$CFLAGS -fsanitize=address -fno-omit-frame-pointer" CXXFLAGS="$CXXFLAGS -fsanitize=address -fno-omit-frame-pointer" make
./picoc -s input

Environment

Ubuntu 16.04
Clang 10.0.1
gcc 5.5

Incorrect prompt returned post condition check

E.g. the final prompt is incorrect

picoc> int a = 1;
picoc> if (a) printf("true\n");
true
     >

The correct output should be:

picoc> int a = 1;
picoc> if (a) printf("true\n");
true
picoc>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.