mirror of
https://github.com/pocketpy/pocketpy
synced 2026-08-06 22:27:11 +08:00
add py_capabilities
This commit is contained in:
parent
01620fcb90
commit
af9dbb39d7
@ -50,6 +50,7 @@ typedef struct VM {
|
||||
py_GlobalRef main; // __main__ module
|
||||
|
||||
py_Callbacks callbacks;
|
||||
py_Capabilities capabilities;
|
||||
|
||||
py_TValue last_retval;
|
||||
py_TValue unhandled_exc;
|
||||
|
||||
@ -13,10 +13,7 @@ typedef struct py_Capabilities {
|
||||
bool (*os_system)(const char* command);
|
||||
bool (*os_remove)(const char* path);
|
||||
// stdc
|
||||
bool stdc_write; // memset, write_bytes, ...
|
||||
bool stdc_read; // memcmp, read_bytes, ...
|
||||
bool stdc_malloc; // malloc
|
||||
bool stdc_free; // free
|
||||
bool stdc;
|
||||
} py_Capabilities;
|
||||
|
||||
/// Setup the capabilities for the current VM.
|
||||
|
||||
@ -93,6 +93,8 @@ void VM__ctor(VM* self) {
|
||||
self->callbacks.flush = pk_default_flush;
|
||||
self->callbacks.getchr = pk_default_getchr;
|
||||
|
||||
memset(&self->capabilities, 0, sizeof(py_Capabilities));
|
||||
|
||||
self->last_retval = *py_NIL();
|
||||
self->unhandled_exc = *py_NIL();
|
||||
|
||||
@ -195,7 +197,7 @@ void VM__ctor(VM* self) {
|
||||
INJECT_BUILTIN_EXC(SyntaxError, tp_Exception);
|
||||
INJECT_BUILTIN_EXC(RecursionError, tp_Exception);
|
||||
INJECT_BUILTIN_EXC(OSError, tp_Exception);
|
||||
INJECT_BUILTIN_EXC(PermissionError, tp_OSError);
|
||||
INJECT_BUILTIN_EXC(PermissionError, tp_Exception);
|
||||
INJECT_BUILTIN_EXC(NotImplementedError, tp_Exception);
|
||||
INJECT_BUILTIN_EXC(TypeError, tp_Exception);
|
||||
INJECT_BUILTIN_EXC(IndexError, tp_Exception);
|
||||
|
||||
@ -38,6 +38,12 @@ static bool os_chdir(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
PY_CHECK_ARG_TYPE(0, tp_str);
|
||||
const char* path = py_tostr(py_arg(0));
|
||||
|
||||
py_Capabilities* caps = py_capabilities();
|
||||
if(!caps->os_chdir || !caps->os_chdir(path)) {
|
||||
return py_exception(tp_PermissionError, "disallowed capability");
|
||||
}
|
||||
|
||||
int code = platform_chdir(path);
|
||||
if(code != 0) {
|
||||
const char* msg = strerror(errno);
|
||||
@ -49,6 +55,12 @@ static bool os_chdir(int argc, py_Ref argv) {
|
||||
|
||||
static bool os_getcwd(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(0);
|
||||
|
||||
py_Capabilities* caps = py_capabilities();
|
||||
if(!caps->os_getcwd || !caps->os_getcwd()) {
|
||||
return py_exception(tp_PermissionError, "disallowed capability");
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
if(!platform_getcwd(buf, sizeof(buf))) return OSError("getcwd() failed");
|
||||
py_newstr(py_retval(), buf);
|
||||
@ -60,6 +72,12 @@ static bool os_system(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARG_TYPE(0, tp_str);
|
||||
#if PK_IS_DESKTOP_PLATFORM
|
||||
const char* cmd = py_tostr(py_arg(0));
|
||||
|
||||
py_Capabilities* caps = py_capabilities();
|
||||
if(!caps->os_system || !caps->os_system(cmd)) {
|
||||
return py_exception(tp_PermissionError, "disallowed capability");
|
||||
}
|
||||
|
||||
int code = system(cmd);
|
||||
py_newint(py_retval(), code);
|
||||
return true;
|
||||
@ -72,6 +90,12 @@ static bool os_remove(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
PY_CHECK_ARG_TYPE(0, tp_str);
|
||||
const char* path = py_tostr(py_arg(0));
|
||||
|
||||
py_Capabilities* caps = py_capabilities();
|
||||
if(!caps->os_remove || !caps->os_remove(path)) {
|
||||
return py_exception(tp_PermissionError, "disallowed capability");
|
||||
}
|
||||
|
||||
int code = remove(path);
|
||||
if(code != 0) {
|
||||
const char* msg = strerror(errno);
|
||||
@ -112,6 +136,12 @@ static bool io_FileIO__new__(int argc, py_Ref argv) {
|
||||
io_FileIO* ud = py_newobject(py_retval(), cls, 0, sizeof(io_FileIO));
|
||||
ud->path = py_tostr(py_arg(1));
|
||||
ud->mode = py_tostr(py_arg(2));
|
||||
|
||||
py_Capabilities* caps = py_capabilities();
|
||||
if(!caps->file_open || !caps->file_open(ud->path, ud->mode)) {
|
||||
return py_exception(tp_PermissionError, "disallowed capability");
|
||||
}
|
||||
|
||||
ud->file = fopen(ud->path, ud->mode);
|
||||
if(ud->file == NULL) {
|
||||
const char* msg = strerror(errno);
|
||||
|
||||
@ -2,8 +2,17 @@
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static bool check_stdc_cap() {
|
||||
py_Capabilities* caps = py_capabilities();
|
||||
if(caps->stdc) return true;
|
||||
return py_exception(tp_PermissionError, "disallowed capability");
|
||||
}
|
||||
|
||||
|
||||
#define DEF_BUILTIN_MEMORY_T(Char_, char_, tp_int_, py_newint_, py_toint_, py_i64_) \
|
||||
static bool stdc_##Char_##__new__(int argc, py_Ref argv) { \
|
||||
if(!check_stdc_cap()) return false; \
|
||||
char_* ud = py_newobject(py_retval(), tp_stdc_##Char_, 0, sizeof(char_)); \
|
||||
if(argc == 2) { \
|
||||
PY_CHECK_ARG_TYPE(1, tp_int_); \
|
||||
@ -14,12 +23,14 @@
|
||||
return true; \
|
||||
} \
|
||||
static bool stdc_##Char_##__get_value(int argc, py_Ref argv) { \
|
||||
if(!check_stdc_cap()) return false; \
|
||||
PY_CHECK_ARGC(1); \
|
||||
char_* ud = py_touserdata(argv); \
|
||||
py_newint_(py_retval(), (py_i64_)(*ud)); \
|
||||
return true; \
|
||||
} \
|
||||
static bool stdc_##Char_##__set_value(int argc, py_Ref argv) { \
|
||||
if(!check_stdc_cap()) return false; \
|
||||
PY_CHECK_ARGC(2); \
|
||||
char_* ud = py_touserdata(argv); \
|
||||
PY_CHECK_ARG_TYPE(1, tp_int_); \
|
||||
@ -28,6 +39,7 @@
|
||||
return true; \
|
||||
} \
|
||||
static bool stdc_##Char_##__read_STATIC(int argc, py_Ref argv) { \
|
||||
if(!check_stdc_cap()) return false; \
|
||||
PY_CHECK_ARGC(2); \
|
||||
PY_CHECK_ARG_TYPE(0, tp_int); \
|
||||
PY_CHECK_ARG_TYPE(1, tp_int); \
|
||||
@ -37,6 +49,7 @@
|
||||
return true; \
|
||||
} \
|
||||
static bool stdc_##Char_##__write_STATIC(int argc, py_Ref argv) { \
|
||||
if(!check_stdc_cap()) return false; \
|
||||
PY_CHECK_ARGC(3); \
|
||||
PY_CHECK_ARG_TYPE(0, tp_int); \
|
||||
PY_CHECK_ARG_TYPE(1, tp_int); \
|
||||
@ -48,6 +61,7 @@
|
||||
return true; \
|
||||
} \
|
||||
static bool stdc_##Char_##__array_STATIC(int argc, py_Ref argv) { \
|
||||
if(!check_stdc_cap()) return false; \
|
||||
PY_CHECK_ARGC(1); \
|
||||
PY_CHECK_ARG_TYPE(0, tp_int); \
|
||||
int length = py_toint(argv); \
|
||||
@ -56,6 +70,7 @@
|
||||
return true; \
|
||||
} \
|
||||
static bool stdc_##Char_##__getitem__(int argc, py_Ref argv) { \
|
||||
if(!check_stdc_cap()) return false; \
|
||||
PY_CHECK_ARGC(2); \
|
||||
char_* ud = py_touserdata(argv); \
|
||||
PY_CHECK_ARG_TYPE(1, tp_int); \
|
||||
@ -64,6 +79,7 @@
|
||||
return true; \
|
||||
} \
|
||||
static bool stdc_##Char_##__setitem__(int argc, py_Ref argv) { \
|
||||
if(!check_stdc_cap()) return false; \
|
||||
PY_CHECK_ARGC(3); \
|
||||
char_* ud = py_touserdata(argv); \
|
||||
PY_CHECK_ARG_TYPE(1, tp_int); \
|
||||
@ -105,6 +121,7 @@ DEF_BUILTIN_MEMORY_T(Bool, bool, tp_bool, py_newbool, py_tobool, bool)
|
||||
#undef DEF_BUILTIN_MEMORY_T
|
||||
|
||||
static bool stdc_malloc(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(1);
|
||||
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||
py_i64 size = py_toint(&argv[0]);
|
||||
@ -114,6 +131,7 @@ static bool stdc_malloc(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_free(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(1);
|
||||
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||
void* p = (void*)(intptr_t)py_toint(&argv[0]);
|
||||
@ -123,6 +141,7 @@ static bool stdc_free(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_memcpy(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(3);
|
||||
PY_CHECK_ARG_TYPE(0, tp_int); // dst
|
||||
void* dst = (void*)(intptr_t)py_toint(&argv[0]);
|
||||
@ -143,6 +162,7 @@ static bool stdc_memcpy(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_memset(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(3);
|
||||
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||
PY_CHECK_ARG_TYPE(1, tp_int);
|
||||
@ -156,6 +176,7 @@ static bool stdc_memset(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_memcmp(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(3);
|
||||
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||
PY_CHECK_ARG_TYPE(1, tp_int);
|
||||
@ -169,6 +190,7 @@ static bool stdc_memcmp(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_addressof(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(1);
|
||||
if(!py_checkinstance(argv, tp_stdc_Memory)) return false;
|
||||
void* ud = py_touserdata(argv);
|
||||
@ -177,6 +199,7 @@ static bool stdc_addressof(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_sizeof(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(1);
|
||||
PY_CHECK_ARG_TYPE(0, tp_type);
|
||||
py_Type type = py_totype(&argv[0]);
|
||||
@ -188,6 +211,7 @@ static bool stdc_sizeof(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_read_cstr(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(1);
|
||||
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||
char* p = (char*)(intptr_t)py_toint(&argv[0]);
|
||||
@ -196,6 +220,7 @@ static bool stdc_read_cstr(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_write_cstr(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(2);
|
||||
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||
PY_CHECK_ARG_TYPE(1, tp_str);
|
||||
@ -208,6 +233,7 @@ static bool stdc_write_cstr(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_read_bytes(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(2);
|
||||
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||
PY_CHECK_ARG_TYPE(1, tp_int);
|
||||
@ -219,6 +245,7 @@ static bool stdc_read_bytes(int argc, py_Ref argv) {
|
||||
}
|
||||
|
||||
static bool stdc_write_bytes(int argc, py_Ref argv) {
|
||||
if(!check_stdc_cap()) return false;
|
||||
PY_CHECK_ARGC(2);
|
||||
PY_CHECK_ARG_TYPE(0, tp_int);
|
||||
PY_CHECK_ARG_TYPE(1, tp_bytes);
|
||||
|
||||
@ -110,6 +110,8 @@ void py_setvmctx(void* ctx) { pk_current_vm->ctx = ctx; }
|
||||
|
||||
py_Callbacks* py_callbacks() { return &pk_current_vm->callbacks; }
|
||||
|
||||
py_Capabilities* py_capabilities() { return &pk_current_vm->capabilities; }
|
||||
|
||||
py_AppCallbacks* py_appcallbacks() {
|
||||
static py_AppCallbacks _callbacks = {0};
|
||||
return &_callbacks;
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
print('sandbox mode, module is disabled')
|
||||
exit()
|
||||
|
||||
try:
|
||||
import os
|
||||
except ImportError:
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
print('sandbox mode, module is disabled')
|
||||
exit()
|
||||
|
||||
try:
|
||||
import os
|
||||
except ImportError:
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
print('sandbox mode, module is disabled')
|
||||
exit()
|
||||
|
||||
try:
|
||||
import os
|
||||
except ImportError:
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
print('sandbox mode, module is disabled')
|
||||
exit()
|
||||
|
||||
try:
|
||||
import os
|
||||
import io
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
print('sandbox mode, module is disabled')
|
||||
exit()
|
||||
|
||||
from stdc import *
|
||||
|
||||
assert sizeof(Int8) == sizeof(UInt8) == 1
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
print('sandbox mode, module is disabled')
|
||||
exit()
|
||||
|
||||
try:
|
||||
import os
|
||||
except ImportError:
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
print('sandbox mode, module is disabled')
|
||||
exit()
|
||||
|
||||
# https://github.com/python/cpython/blob/v3.4.10/Lib/test/test_math.py
|
||||
|
||||
# Python test set -- math module
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user