mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
builtin: do not use unsafe sprintf/vsprintf functions
This commit is contained in:
parent
7e139b5384
commit
c21e976cad
@ -195,28 +195,3 @@ pub fn is_atty(fd int) int {
|
||||
return C.isatty(fd)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn C.va_start()
|
||||
fn C.va_end()
|
||||
fn C.vsnprintf() int
|
||||
fn C.vsprintf() int
|
||||
|
||||
pub fn str2_(fmt charptr, ...) string {
|
||||
argptr := C.va_list{}
|
||||
C.va_start(argptr, fmt)
|
||||
len := C.vsnprintf(0, 0, fmt, argptr) + 1
|
||||
C.va_end(argptr)
|
||||
buf := malloc(len)
|
||||
C.va_start(argptr, fmt)
|
||||
C.vsprintf(charptr(buf), fmt, argptr)
|
||||
C.va_end(argptr)
|
||||
//#ifdef DEBUG_ALLOC
|
||||
// puts("_STR:");
|
||||
// puts(buf);
|
||||
//#endif
|
||||
return tos2(buf)
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
@ -110,24 +110,35 @@ fn (v &V) generate_hot_reload_code() {
|
||||
cgen.genln('
|
||||
|
||||
void lfnmutex_print(char *s){
|
||||
if(0){
|
||||
#if 0
|
||||
fflush(stderr);
|
||||
fprintf(stderr,">> live_fn_mutex: %p | %s\\n", &live_fn_mutex, s);
|
||||
fflush(stderr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
')
|
||||
if v.pref.os != .windows {
|
||||
cgen.genln('
|
||||
#define _POSIX_C_SOURCE 1
|
||||
#include <limits.h>
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
void* live_lib = 0;
|
||||
|
||||
int load_so(byteptr path) {
|
||||
char cpath[1024];
|
||||
sprintf(cpath,"./%s", path);
|
||||
char cpath[PATH_MAX] = {0};
|
||||
int res = snprintf(cpath, sizeof (cpath), "./%s", path);
|
||||
if (res >= sizeof (cpath)) {
|
||||
fprintf (stderr, "path is too long");
|
||||
return 0;
|
||||
}
|
||||
//printf("load_so %s\\n", cpath);
|
||||
if (live_lib) dlclose(live_lib);
|
||||
live_lib = dlopen(cpath, RTLD_LAZY);
|
||||
if (!live_lib) {
|
||||
puts("open failed");
|
||||
fprintf(stderr, "open failed");
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
||||
@ -138,6 +149,11 @@ int load_so(byteptr path) {
|
||||
}
|
||||
else {
|
||||
cgen.genln('
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
void pthread_mutex_lock(HANDLE *m) {
|
||||
WaitForSingleObject(*m, INFINITE);
|
||||
}
|
||||
@ -146,14 +162,19 @@ void pthread_mutex_unlock(HANDLE *m) {
|
||||
ReleaseMutex(*m);
|
||||
}
|
||||
|
||||
void* live_lib=0;
|
||||
void* live_lib = NULL;
|
||||
int load_so(byteptr path) {
|
||||
char cpath[1024];
|
||||
sprintf(cpath, "./%s", path);
|
||||
char cpath[PATH_MAX];
|
||||
int res = snprintf(cpath, sizeof (cpath), "./%s", path);
|
||||
if (res >= sizeof(cpath)) {
|
||||
puts("path is too long\\n");
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
||||
if (live_lib) FreeLibrary(live_lib);
|
||||
live_lib = LoadLibraryA(cpath);
|
||||
if (!live_lib) {
|
||||
puts("open failed");
|
||||
puts("open failed\\n");
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
||||
@ -167,9 +188,9 @@ int load_so(byteptr path) {
|
||||
|
||||
int _live_reloads = 0;
|
||||
void reload_so() {
|
||||
char new_so_base[1024];
|
||||
char new_so_name[1024];
|
||||
char compile_cmd[1024];
|
||||
char new_so_base[PATH_MAX] = {0};
|
||||
char new_so_name[PATH_MAX] = {0};
|
||||
char compile_cmd[PATH_MAX] = {0};
|
||||
int last = os__file_last_mod_unix(tos2("$file"));
|
||||
while (1) {
|
||||
// TODO use inotify
|
||||
@ -179,22 +200,22 @@ void reload_so() {
|
||||
_live_reloads++;
|
||||
|
||||
//v -o bounce -shared bounce.v
|
||||
sprintf(new_so_base, ".tmp.%d.${file_base}", _live_reloads);
|
||||
snprintf(new_so_base, sizeof (new_so_base), ".tmp.%d.${file_base}", _live_reloads);
|
||||
#ifdef _WIN32
|
||||
// We have to make this directory becuase windows WILL NOT
|
||||
// do it for us
|
||||
os__mkdir(string_all_before_last(tos2(new_so_base), tos2("/")));
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
sprintf(new_so_name, "%s.dll", new_so_base);
|
||||
snprintf(new_so_name, sizeof (new_so_name), "%s.dll", new_so_base);
|
||||
#else
|
||||
sprintf(new_so_name, "%s.so", new_so_base);
|
||||
snprintf(new_so_name, sizeof (new_so_name), "%s.so", new_so_base);
|
||||
#endif
|
||||
sprintf(compile_cmd, "$vexe $msvc -o %s -solive -shared $file", new_so_base);
|
||||
snprintf(compile_cmd, sizeof (compile_cmd), "$vexe $msvc -o %s -solive -shared $file", new_so_base);
|
||||
os__system(tos2(compile_cmd));
|
||||
|
||||
if( !os__exists(tos2(new_so_name)) ) {
|
||||
fprintf(stderr, "Errors while compiling $file\\n");
|
||||
puts("Errors while compiling $file\\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
97
vlib/compiler/tests/live_test.v
Executable file
97
vlib/compiler/tests/live_test.v
Executable file
@ -0,0 +1,97 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
const (
|
||||
vexe = os.getenv('VEXE')
|
||||
source_file = os.join_path(os.temp_dir(), 'generated_live_program.v')
|
||||
output_file = os.join_path(os.temp_dir(), 'generated_live_program.output.txt')
|
||||
live_program_source = "
|
||||
module main
|
||||
import time
|
||||
|
||||
[live]
|
||||
fn pmessage() {
|
||||
println('ORIGINAL')
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println('START')
|
||||
for i := 0; i<6*100; i++ {
|
||||
pmessage()
|
||||
time.sleep_ms(10)
|
||||
}
|
||||
println('END')
|
||||
}
|
||||
"
|
||||
)
|
||||
|
||||
//
|
||||
|
||||
fn testsuite_begin(){
|
||||
if os.user_os() != 'linux' && os.getenv('FORCE_LIVE_TEST').len == 0 {
|
||||
eprintln('Testing the runtime behaviour of -live mode,')
|
||||
eprintln('is reliable only on Linux for now.')
|
||||
eprintln('You can still do it by setting FORCE_LIVE_TEST=1 .')
|
||||
exit(0)
|
||||
}
|
||||
os.write_file(source_file, live_program_source)
|
||||
}
|
||||
|
||||
fn testsuite_end(){
|
||||
os.rm( source_file )
|
||||
eprintln('source: $source_file')
|
||||
eprintln('output: $output_file')
|
||||
$if !windows {
|
||||
os.system('cat $output_file')
|
||||
}
|
||||
println('---------------------------------------------------------------------------')
|
||||
output_lines := os.read_lines( output_file ) or {
|
||||
return
|
||||
}
|
||||
mut histogram := map[string]int
|
||||
for line in output_lines {
|
||||
histogram[line] = histogram[line] + 1
|
||||
}
|
||||
for k,v in histogram {
|
||||
println('> found ${k} $v times.')
|
||||
}
|
||||
println('---------------------------------------------------------------------------')
|
||||
assert histogram['START'] > 0
|
||||
assert histogram['END'] > 0
|
||||
assert histogram['CHANGED'] + histogram['ANOTHER'] > 0
|
||||
assert histogram['ORIGINAL'] > 0
|
||||
}
|
||||
|
||||
fn change_source(new string){
|
||||
time.sleep_ms(250)
|
||||
eprintln('> change ORIGINAL to: $new')
|
||||
os.write_file(source_file,live_program_source.replace('ORIGINAL', new))
|
||||
time.sleep_ms(1000)
|
||||
eprintln('> done.')
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
fn test_live_program_can_be_compiled(){
|
||||
cmd := '$vexe -live run $source_file > $output_file &'
|
||||
eprintln('Compiling and running with: $cmd')
|
||||
res := os.system(cmd)
|
||||
eprintln('... running in the background')
|
||||
time.sleep_ms(3000)
|
||||
assert res == 0
|
||||
}
|
||||
|
||||
fn test_live_program_can_be_changed_1(){
|
||||
change_source('CHANGED')
|
||||
assert true
|
||||
}
|
||||
|
||||
fn test_live_program_can_be_changed_2(){
|
||||
change_source('ANOTHER')
|
||||
assert true
|
||||
}
|
||||
|
||||
fn test_live_program_has_ended(){
|
||||
time.sleep_ms(10*1000)
|
||||
assert true
|
||||
}
|
@ -42,7 +42,7 @@ pub fn parse_rfc2822(s string) ?Time {
|
||||
mm := pos / 3 + 1
|
||||
mut tmstr := byteptr(0)
|
||||
unsafe { tmstr = malloc(s.len * 2) }
|
||||
count := C.sprintf(charptr(tmstr), '%s-%02d-%s %s', fields[3].str, mm,
|
||||
count := C.snprintf(charptr(tmstr), (s.len * 2), '%s-%02d-%s %s', fields[3].str, mm,
|
||||
fields[1].str, fields[4].str)
|
||||
|
||||
t := parse(tos(tmstr, count)) or {
|
||||
|
Loading…
Reference in New Issue
Block a user