Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save avivbeeri/6896e8d77c17123e03154a52fb0308f8 to your computer and use it in GitHub Desktop.
Save avivbeeri/6896e8d77c17123e03154a52fb0308f8 to your computer and use it in GitHub Desktop.
Stack Corruption in Wren
#include <stdio.h>
#include "wren.h"
char* script = " class Colored { \n"
" foreign static point(a, b)\n"
" }\n"
" class App { \n"
" \n"
" static update() {\n"
" var red = [1, 0, 0, 1]\n"
" Colored.point([200, 200], red)\n"
" Colored.point([100, 100], red) \n"
" Colored.point([50, 50], red)\n"
" }\n"
" }\n";
/* ErrorFn is taken from the Wren Embedding documentation, so it's pure C */
void errorFn(WrenVM* vm, WrenErrorType errorType,
const char* module, const int line,
const char* msg)
{
switch (errorType)
{
case WREN_ERROR_COMPILE:
{
printf("[%s line %d] [Error] %s\n", module, line, msg);
} break;
case WREN_ERROR_STACK_TRACE:
{
printf("[%s line %d] in %s\n", module, line, msg);
} break;
case WREN_ERROR_RUNTIME:
{
printf("[Runtime Error] %s\n", msg);
} break;
}
}
/* Copied from Stelleron's Code */
void writeFn(WrenVM* vm, const char* str) {
printf("%s\n", str);
}
void drawPoint(WrenVM* vm){
// Colored_class, [xy], [rgb(a)], x, y, r, g, b, (a)
WrenHandle* first = wrenGetSlotHandle(vm, 1);
WrenHandle* second = wrenGetSlotHandle(vm, 2);
wrenEnsureSlots(vm, 9);
wrenSetSlotHandle(vm, 1, first);
wrenSetSlotHandle(vm, 2, second);
if(wrenGetSlotType(vm, 1) != WREN_TYPE_LIST || wrenGetListCount(vm, 1) != 2){
wrenSetSlotString(vm, 1, "[xy] shoud be a List of 2 numbers");
wrenAbortFiber(vm, 1);
return;
}
if (wrenGetSlotType(vm, 2) != WREN_TYPE_LIST)v{
wrenSetSlotString(vm, 1, "[rgba] shoud be a List of 4 numbers");
wrenAbortFiber(vm, 1);
return;
}
if(wrenGetListCount(vm, 2) != 4){
wrenSetSlotString(vm, 1, "[rgba] shoud be a List of 4 numbers bis");
wrenAbortFiber(vm, 1);
return;
}
wrenGetListElement(vm, 1, 0, 3);
wrenGetListElement(vm, 1, 1, 4);
wrenGetListElement(vm, 2, 0, 5);
wrenGetListElement(vm, 2, 1, 6);
wrenGetListElement(vm, 2, 2, 7);
wrenGetListElement(vm, 2, 3, 8);
if(wrenGetSlotType(vm, 3) != WREN_TYPE_NUM || wrenGetSlotType(vm, 4) != WREN_TYPE_NUM){
wrenSetSlotString(vm, 1, "[xy] shoud be a List of 2 numbers bis");
wrenAbortFiber(vm, 1);
return;
}
if(wrenGetSlotType(vm, 5) != WREN_TYPE_NUM || wrenGetSlotType(vm, 6) != WREN_TYPE_NUM || wrenGetSlotType(vm, 7) != WREN_TYPE_NUM || wrenGetSlotType(vm, 8) != WREN_TYPE_NUM){
wrenSetSlotString(vm, 1, "[rgba] shoud be a List of 4 numbers ter");
wrenAbortFiber(vm, 1);
return;
}
double x = wrenGetSlotDouble(vm, 3);
double y = wrenGetSlotDouble(vm, 4);
double r = wrenGetSlotDouble(vm, 5);
double g = wrenGetSlotDouble(vm, 6);
double b = wrenGetSlotDouble(vm, 7);
double a = wrenGetSlotDouble(vm, 8);
wrenReleaseHandle(vm, first);
wrenReleaseHandle(vm, second);
printf("finish call\n");
}
WrenForeignMethodFn bind(struct WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature) {
return drawPoint;
}
int main() {
// create the configuration that the virtual machine will use
WrenConfiguration config;
// Initialise the config
wrenInitConfiguration(&config);
config.writeFn = writeFn;
config.errorFn = errorFn;
config.loadModuleFn = NULL;
config.bindForeignMethodFn = bind;
WrenVM* vm = wrenNewVM(&config);
// do something with your vm!
WrenInterpretResult result = wrenInterpret(vm, "main", script);
WrenHandle* call = wrenMakeCallHandle(vm, "update()");
wrenEnsureSlots(vm, 1);
wrenGetVariable(vm, "main", "App", 0);
wrenCall(vm, call);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment