From 1531002f2693fc5dd4b3331ca4576ea99935d357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Santos=20Costa?= Date: Sat, 18 Feb 2012 11:01:06 +0000 Subject: [PATCH] avoid unnecessrily using slots in Input/Output calls or just because I need a stream. This can lead to hard to catch stack bugs. --- C/c_interface.c | 6 ++--- C/iopreds.c | 15 +++++++---- C/pl-yap.c | 15 ----------- C/qlyr.c | 22 ++++++++++++++-- C/qlyw.c | 22 ++++++++++++++-- H/Yapproto.h | 8 +++--- H/pl-yap.h | 3 ++- OPTYap/opt.preds.c | 64 ++++++++++++++++++++++++++++++++-------------- os/pl-file.c | 56 +++++++++++++++++++++++++++++++++++++++- 9 files changed, 158 insertions(+), 53 deletions(-) diff --git a/C/c_interface.c b/C/c_interface.c index f05267f87..ef9593fbc 100644 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -2704,11 +2704,11 @@ YAP_TermToStream(Term t) { CACHE_REGS IOSTREAM *s; - int rc; - extern int PL_get_stream_handle(Int t, IOSTREAM **s); BACKUP_MACHINE_REGS(); - if ( (rc=PL_get_stream_handle(Yap_InitSlot(t PASS_REGS), &s)) ) { + if (IsVarTerm(t) || !IsAtomTerm(t)) + return NULL; + if ( (s=Yap_GetStreamHandle(AtomOfTerm(t))) ) { RECOVER_MACHINE_REGS(); return s; } diff --git a/C/iopreds.c b/C/iopreds.c index 877b40ec3..6f6a3acf2 100644 --- a/C/iopreds.c +++ b/C/iopreds.c @@ -745,19 +745,24 @@ p_read ( USES_REGS1 ) return do_read(Yap_Scurin(), 7 PASS_REGS); } -extern int Yap_getInputStream(Int, IOSTREAM **); - static Int p_read2 ( USES_REGS1 ) { /* '$read2'(+Flag,?Term,?Module,?Vars,-Pos,-Err,+Stream) */ IOSTREAM *inp_stream; Int out; + Term t8 = Deref(ARG8); - if (!Yap_getInputStream(Yap_InitSlot(Deref(ARG8) PASS_REGS), &inp_stream)) { - Yap_RecoverSlots(1 PASS_REGS); + if (IsVarTerm(t8)) { + Yap_Error(INSTANTIATION_ERROR,t8,"read_term/3"); + return FALSE; + } + if (!IsAtomTerm(t8)) { + Yap_Error(TYPE_ERROR_LIST,t8,"read_term/3"); + return(FALSE); + } + if (!(inp_stream = Yap_GetInputStream(AtomOfTerm(t8))) ) { return(FALSE); } - Yap_RecoverSlots(1 PASS_REGS); out = do_read(inp_stream, 8 PASS_REGS); return out; } diff --git a/C/pl-yap.c b/C/pl-yap.c index 73044a4fc..197a1f422 100644 --- a/C/pl-yap.c +++ b/C/pl-yap.c @@ -989,21 +989,6 @@ int PL_unify_integer__LD(term_t t, intptr_t i ARG_LD) return Yap_unify(Yap_GetFromSlot(t PASS_REGS),iterm); } -extern int Yap_getInputStream(term_t t, IOSTREAM **s); - -int Yap_getInputStream(term_t t, IOSTREAM **s) -{ - GET_LD - return getInputStream(t, s); -} - -extern int Yap_getOutputStream(term_t t, IOSTREAM **s); - -int Yap_getOutputStream(term_t t, IOSTREAM **s) -{ - GET_LD - return getOutputStream(t, s); -} #ifdef _WIN32 diff --git a/C/qlyr.c b/C/qlyr.c index b8f4ffd03..aa588fbf6 100644 --- a/C/qlyr.c +++ b/C/qlyr.c @@ -976,8 +976,17 @@ static Int p_read_module_preds( USES_REGS1 ) { IOSTREAM *stream; + Term t1 = Deref(ARG1); - if (!Yap_getInputStream(Yap_InitSlot(Deref(ARG1) PASS_REGS), &stream)) { + if (IsVarTerm(t1)) { + Yap_Error(INSTANTIATION_ERROR,t1,"read_qly/3"); + return FALSE; + } + if (!IsAtomTerm(t1)) { + Yap_Error(TYPE_ERROR_ATOM,t1,"read_qly/3"); + return(FALSE); + } + if (!(stream = Yap_GetInputStream(AtomOfTerm(t1))) ) { return FALSE; } read_module(stream); @@ -989,8 +998,17 @@ p_read_program( USES_REGS1 ) { IOSTREAM *stream; void YAP_Reset(void); + Term t1 = Deref(ARG1); - if (!Yap_getInputStream(Yap_InitSlot(Deref(ARG1) PASS_REGS), &stream)) { + if (IsVarTerm(t1)) { + Yap_Error(INSTANTIATION_ERROR,t1,"read_program/3"); + return FALSE; + } + if (!IsAtomTerm(t1)) { + Yap_Error(TYPE_ERROR_ATOM,t1,"read_program/3"); + return(FALSE); + } + if (!(stream = Yap_GetInputStream(AtomOfTerm(t1))) ) { return FALSE; } YAP_Reset(); diff --git a/C/qlyw.c b/C/qlyw.c index 4e13941f3..2992768f5 100644 --- a/C/qlyw.c +++ b/C/qlyw.c @@ -701,8 +701,17 @@ p_save_module_preds( USES_REGS1 ) { IOSTREAM *stream; Term tmod = Deref(ARG2); + Term t1 = Deref(ARG1); - if (!Yap_getOutputStream(Yap_InitSlot(Deref(ARG1) PASS_REGS), &stream)) { + if (IsVarTerm(t1)) { + Yap_Error(INSTANTIATION_ERROR,t1,"save_module/3"); + return FALSE; + } + if (!IsAtomTerm(t1)) { + Yap_Error(TYPE_ERROR_ATOM,t1,"save_module/3"); + return(FALSE); + } + if (!(stream = Yap_GetOutputStream(AtomOfTerm(t1))) ) { return FALSE; } if (IsVarTerm(tmod)) { @@ -720,8 +729,17 @@ static Int p_save_program( USES_REGS1 ) { IOSTREAM *stream; + Term t1 = Deref(ARG1); - if (!Yap_getOutputStream(Yap_InitSlot(Deref(ARG1) PASS_REGS), &stream)) { + if (IsVarTerm(t1)) { + Yap_Error(INSTANTIATION_ERROR,t1,"save_program/3"); + return FALSE; + } + if (!IsAtomTerm(t1)) { + Yap_Error(TYPE_ERROR_ATOM,t1,"save_program/3"); + return(FALSE); + } + if (!(stream = Yap_GetOutputStream(AtomOfTerm(t1))) ) { return FALSE; } return save_program(stream) != 0; diff --git a/H/Yapproto.h b/H/Yapproto.h index 1454d9fba..7d6c2030f 100644 --- a/H/Yapproto.h +++ b/H/Yapproto.h @@ -257,11 +257,13 @@ int STD_PROTO(Yap_eq,(Term, Term)); /* iopreds.c */ void STD_PROTO(Yap_InitBackIO,(void)); void STD_PROTO(Yap_InitIOPreds,(void)); +void *Yap_GetStreamHandle(Atom at); +void *Yap_GetInputStream(Atom at); +void *Yap_GetOutputStream(Atom at); #ifdef DEBUG extern void Yap_DebugPlWrite (Term t); extern void Yap_DebugErrorPutc (int n); #endif -int STD_PROTO(Yap_LookupSWIStream,(void *)); int STD_PROTO(Yap_readTerm, (void *, Term *, Term *, Term *, Term *)); void STD_PROTO(Yap_PlWriteToStream, (Term, int, int)); /* depth_lim.c */ @@ -502,8 +504,4 @@ gc_P(yamop *p, yamop *cp) return (p->opc == Yap_opcode(_execute_cpred) ? cp : p); } -#ifdef _PL_STREAM_H -extern int Yap_getInputStream(Int t, IOSTREAM **s); -extern int Yap_getOutputStream(Int t, IOSTREAM **s); -#endif diff --git a/H/pl-yap.h b/H/pl-yap.h index 34f98ec14..2a7f89521 100644 --- a/H/pl-yap.h +++ b/H/pl-yap.h @@ -31,11 +31,12 @@ typedef YAP_Term (*Func)(term_t); /* foreign functions */ extern const char *Yap_GetCurrentPredName(void); extern YAP_Int Yap_GetCurrentPredArity(void); extern int Yap_read_term(term_t t, IOSTREAM *st, term_t *exc, term_t vs); -extern int Yap_LookupSWIStream(void *swi_s); extern term_t Yap_fetch_module_for_format(term_t args, YAP_Term *modp); extern IOENC Yap_DefaultEncoding(void); extern void Yap_SetDefaultEncoding(IOENC); +extern void *Yap_GetStreamHandle(Atom at); + extern atom_t codeToAtom(int chrcode); #define valTermRef(t) ((Word)YAP_AddressFromSlot(t)) diff --git a/OPTYap/opt.preds.c b/OPTYap/opt.preds.c index 4cafc5fd1..909dfd201 100644 --- a/OPTYap/opt.preds.c +++ b/OPTYap/opt.preds.c @@ -484,9 +484,12 @@ static Int p_abolish_all_tables( USES_REGS1 ) { static Int p_show_tabled_predicates( USES_REGS1 ) { IOSTREAM *out; tab_ent_ptr tab_ent; + Term t = Deref(ARG1); - if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out)) - return (FALSE); + if (IsVarTerm(t) || !IsAtomTerm(t)) + return FALSE; + if (!(out = Yap_GetStreamHandle(AtomOfTerm(t)))) + return FALSE; tab_ent = GLOBAL_root_tab_ent; Sfprintf(out, "Tabled predicates\n"); if (tab_ent == NULL) @@ -504,9 +507,12 @@ static Int p_show_table( USES_REGS1 ) { IOSTREAM *out; Term mod, t; tab_ent_ptr tab_ent; + Term t1 = Deref(ARG1); - if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out)) - return (FALSE); + if (IsVarTerm(t1) || !IsAtomTerm(t1)) + return FALSE; + if (!(out = Yap_GetStreamHandle(AtomOfTerm(t1)))) + return FALSE; mod = Deref(ARG2); t = Deref(ARG3); if (IsAtomTerm(t)) @@ -526,9 +532,12 @@ static Int p_show_table( USES_REGS1 ) { static Int p_show_all_tables( USES_REGS1 ) { IOSTREAM *out; tab_ent_ptr tab_ent; + Term t = Deref(ARG1); - if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out)) - return (FALSE); + if (IsVarTerm(t) || !IsAtomTerm(t)) + return FALSE; + if (!(out = Yap_GetStreamHandle(AtomOfTerm(t)))) + return FALSE; tab_ent = GLOBAL_root_tab_ent; while(tab_ent) { show_table(tab_ent, SHOW_MODE_STRUCTURE, out); @@ -541,9 +550,12 @@ static Int p_show_all_tables( USES_REGS1 ) { static Int p_show_global_trie( USES_REGS1 ) { IOSTREAM *out; + Term t = Deref(ARG1); - if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out)) - return (FALSE); + if (IsVarTerm(t) || !IsAtomTerm(t)) + return FALSE; + if (!(out = Yap_GetStreamHandle(AtomOfTerm(t)))) + return FALSE; show_global_trie(SHOW_MODE_STRUCTURE, out); PL_release_stream(out); return (TRUE); @@ -554,9 +566,12 @@ static Int p_show_statistics_table( USES_REGS1 ) { IOSTREAM *out; Term mod, t; tab_ent_ptr tab_ent; + Term t1 = Deref(ARG1); - if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out)) - return (FALSE); + if (IsVarTerm(t1) || !IsAtomTerm(t1)) + return FALSE; + if (!(out = Yap_GetStreamHandle(AtomOfTerm(t1)))) + return FALSE; mod = Deref(ARG2); t = Deref(ARG3); if (IsAtomTerm(t)) @@ -580,9 +595,12 @@ static Int p_show_statistics_tabling( USES_REGS1 ) { long total_pages = 0; #endif /* USE_PAGES_MALLOC */ IOSTREAM *out; + Term t = Deref(ARG1); - if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out)) - return (FALSE); + if (IsVarTerm(t) || !IsAtomTerm(t)) + return FALSE; + if (!(out = Yap_GetStreamHandle(AtomOfTerm(t)))) + return FALSE; bytes = 0; Sfprintf(out, "Execution data structures\n"); stats = show_statistics_table_entries(out); @@ -636,9 +654,12 @@ static Int p_show_statistics_tabling( USES_REGS1 ) { static Int p_show_statistics_global_trie( USES_REGS1 ) { IOSTREAM *out; + Term t = Deref(ARG1); - if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out)) - return (FALSE); + if (IsVarTerm(t) || !IsAtomTerm(t)) + return FALSE; + if (!(out = Yap_GetStreamHandle(AtomOfTerm(t)))) + return FALSE; show_global_trie(SHOW_MODE_STATISTICS, out); PL_release_stream(out); return (TRUE); @@ -765,9 +786,12 @@ static Int p_show_statistics_or( USES_REGS1 ) { long total_pages = 0; #endif /* USE_PAGES_MALLOC */ IOSTREAM *out; + Term t = Deref(ARG1); - if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out)) - return (FALSE); + if (IsVarTerm(t) || !IsAtomTerm(t)) + return FALSE; + if (!(out = Yap_GetStreamHandle(AtomOfTerm(t)))) + return FALSE; bytes = 0; Sfprintf(out, "Execution data structures\n"); stats = show_statistics_or_frames(out); @@ -808,10 +832,12 @@ static Int p_show_statistics_opt( USES_REGS1 ) { #ifdef USE_PAGES_MALLOC long total_pages = 0; #endif /* USE_PAGES_MALLOC */ - IOSTREAM *out; + Term t = Deref(ARG1); - if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out)) - return (FALSE); + if (IsVarTerm(t) || !IsAtomTerm(t)) + return FALSE; + if (!(out = Yap_GetStreamHandle(AtomOfTerm(t)))) + return FALSE; bytes = 0; Sfprintf(out, "Execution data structures\n"); stats = show_statistics_table_entries(out); diff --git a/os/pl-file.c b/os/pl-file.c index 300211c3d..d02f13036 100644 --- a/os/pl-file.c +++ b/os/pl-file.c @@ -636,7 +636,6 @@ PL_get_stream_handle(term_t t, IOSTREAM **s) return term_stream_handle(t, s, SH_ERRORS|SH_ALIAS PASS_LD); } - static int unify_stream_ref(term_t t, IOSTREAM *s) { GET_LD @@ -4672,6 +4671,61 @@ EndPredDefs #if __YAP_PROLOG__ +void * +Yap_GetStreamHandle(Atom at) +{ atom_t a; + IOSTREAM *s; + + a = YAP_SWIAtomFromAtom(at); + if (!get_stream_handle(a, &s, SH_ERRORS|SH_ALIAS)) + return NULL; + return s; +} + +void *Yap_GetInputStream(Atom at) +{ atom_t a; + IOSTREAM *s; + if ( at == AtomUser ) { + if ( (s = getStream(Suser_input)) ) + return s; + return NULL; + } + + a = YAP_SWIAtomFromAtom(at); + if ( !get_stream_handle(a, &s, SH_ERRORS|SH_ALIAS|SH_INPUT) ) + return NULL; + + if ( !(s->flags &SIO_INPUT) ) + { releaseStream(s); + return Yap_Error(PERMISSION_ERROR_INPUT_STREAM, MkAtomTerm(at), + "read or ql"); + return NULL; + } + return s; +} + +void *Yap_GetOutputStream(Atom at) +{ atom_t a; + IOSTREAM *s; + if ( at == AtomUser ) { + if ( (s = getStream(Suser_output)) ) + return s; + return NULL; + } + + a = YAP_SWIAtomFromAtom(at); + if ( !get_stream_handle(a, &s, SH_ERRORS|SH_ALIAS|SH_OUTPUT) ) + return NULL; + + if ( !(s->flags &SIO_OUTPUT) ) + { releaseStream(s); + return Yap_Error(PERMISSION_ERROR_OUTPUT_STREAM, MkAtomTerm(at), + "write or ql"); + return NULL; + } + return s; +} + static int pl_get_time(term_t t) { return PL_unify_float(t, WallTime());