diff options
author | Don Kjer <don@lindenlab.com> | 2007-09-28 23:32:53 +0000 |
---|---|---|
committer | Don Kjer <don@lindenlab.com> | 2007-09-28 23:32:53 +0000 |
commit | b089fc559a5dc527ed5e0422e82abf3b1dd5f1b2 (patch) | |
tree | baa68e98452406c03a3dbe21c99a901f769c8890 /indra/lscript | |
parent | ab8dd2b55008090a1f18fb107f897c736d98a760 (diff) |
EFFECTIVE MERGE: svn merge -r 68999:69916 svn+ssh://svn.lindenlab.com/svn/linden/branches/maintenance into release
** This should be the last merge from branches/maintenance. All future merges will be from new maintenance-# branches off release **
ACTUAL MERGE: svn merge -r70609:70621 svn+ssh://svn/svn/linden/branches/maintenance-0-qa-r70556
RELATED MERGE: svn merge -r69921:70316 svn+ssh://svn/svn/linden/branches/maintenance-0-qa
Diffstat (limited to 'indra/lscript')
-rw-r--r-- | indra/lscript/lscript_byteconvert.h | 41 | ||||
-rw-r--r-- | indra/lscript/lscript_execute.h | 4 | ||||
-rw-r--r-- | indra/lscript/lscript_execute/lscript_execute.cpp | 160 |
3 files changed, 155 insertions, 50 deletions
diff --git a/indra/lscript/lscript_byteconvert.h b/indra/lscript/lscript_byteconvert.h index d30c84b28c..d960eb8c66 100644 --- a/indra/lscript/lscript_byteconvert.h +++ b/indra/lscript/lscript_byteconvert.h @@ -761,9 +761,17 @@ inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEven major_version = LSL2_MAJOR_VERSION_TWO; state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state; } + if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY ) + { + return -1; + } // get the actual position in memory of the desired state S32 state_offset = sr + bytestream2integer(stream, state_offset_offset); + if ( state_offset < 0 || state_offset > TOP_OF_MEMORY ) + { + return -1; + } // save that value S32 state_offset_base = state_offset; @@ -773,18 +781,32 @@ inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEven // get the location of the event offset S32 event_offset = event_jump_offset + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event); + if ( event_offset < 0 || event_offset > TOP_OF_MEMORY ) + { + return -1; + } // now, jump to the event S32 event_start = bytestream2integer(stream, event_offset); + if ( event_start < 0 || event_start > TOP_OF_MEMORY ) + { + return -1; + } event_start += event_jump_offset; S32 event_start_original = event_start; // now skip past the parameters S32 opcode_offset = bytestream2integer(stream, event_start); + if ( opcode_offset < 0 || opcode_offset > TOP_OF_MEMORY ) + { + return -1; + } + return opcode_offset + event_start_original; } + inline U64 get_handled_events(U8 *stream, S32 state) { U64 retvalue = 0; @@ -809,6 +831,7 @@ inline U64 get_handled_events(U8 *stream, S32 state) return retvalue; } +// Returns -1 on error inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event) { // get the start of the state table @@ -829,21 +852,39 @@ inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType eve state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state; } + if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY ) + { + return -1; + } + S32 state_offset = bytestream2integer(stream, state_offset_offset); state_offset += sr; state_offset_offset = state_offset; + if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY ) + { + return -1; + } // skip to jump table S32 jump_table = bytestream2integer(stream, state_offset_offset); jump_table += state_offset; + if ( jump_table < 0 || jump_table > TOP_OF_MEMORY ) + { + return -1; + } // get the position of the jump to the desired state S32 stack_size_offset = jump_table + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event) + LSCRIPTDataSize[LST_INTEGER]; // get the handled events S32 stack_size = bytestream2integer(stream, stack_size_offset); + if ( stack_size < 0 || stack_size > TOP_OF_MEMORY ) + { + return -1; + } + return stack_size; } diff --git a/indra/lscript/lscript_execute.h b/indra/lscript/lscript_execute.h index 84cd6e3b0a..1c2952f5ae 100644 --- a/indra/lscript/lscript_execute.h +++ b/indra/lscript/lscript_execute.h @@ -359,6 +359,10 @@ public: LLScriptEventData mEventData; static S64 sGlobalInstructionCount; + +private: + void recordBoundaryError( const LLUUID &id ); + void setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id ); }; #endif diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp index b166e922a2..d00d3372ce 100644 --- a/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/indra/lscript/lscript_execute/lscript_execute.cpp @@ -245,6 +245,32 @@ void LLScriptExecute::init() } + +// Utility routine for when there's a boundary error parsing bytecode +void LLScriptExecute::recordBoundaryError( const LLUUID &id ) +{ + set_fault(mBuffer, LSRF_BOUND_CHECK_ERROR); + llwarns << "Script boundary error for ID " << id << llendl; +} + + +// set IP to the event handler with some error checking +void LLScriptExecute::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id ) +{ + S32 opcode_start = get_state_event_opcoode_start( mBuffer, state, event ); + if ( opcode_start == -1 ) + { + recordBoundaryError( id ); + } + else + { + set_ip( mBuffer, opcode_start ); + } +} + + + + S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer); U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &state_transition) @@ -353,14 +379,20 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL & // now, push any additional stack space S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT); - lscript_pusharge(mBuffer, additional_size); - - sp = get_register(mBuffer, LREG_SP); - sp += additional_size; - set_bp(mBuffer, sp); - // set IP to the event handler - S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, LSTT_STATE_EXIT); - set_ip(mBuffer, opcode_start); + if ( additional_size == -1 ) + { + recordBoundaryError( id ); + } + else + { + lscript_pusharge(mBuffer, additional_size); + + sp = get_register(mBuffer, LREG_SP); + sp += additional_size; + set_bp(mBuffer, sp); + // set IP to the event handler + setStateEventOpcoodeStartSafely( current_state, LSTT_STATE_EXIT, id ); + } return NO_DELETE_FLAG; } } @@ -411,20 +443,27 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL & current_events &= ~LSCRIPTStateBitField[event]; set_event_register(mBuffer, LREG_CE, current_events, major_version); // now, push any additional stack space - S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size; - lscript_pusharge(mBuffer, additional_size); + S32 additional_size = get_event_stack_size(mBuffer, current_state, event); + if ( additional_size == -1 ) + { // b_done will be set, so we'll exit the loop at the bottom + recordBoundaryError( id ); + } + else + { + additional_size -= size; + lscript_pusharge(mBuffer, additional_size); // now set the bp correctly - sp = get_register(mBuffer, LREG_SP); - sp += additional_size + size; - set_bp(mBuffer, sp); + sp = get_register(mBuffer, LREG_SP); + sp += additional_size + size; + set_bp(mBuffer, sp); // set IP to the function - S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event); - set_ip(mBuffer, opcode_start); + setStateEventOpcoodeStartSafely( current_state, event, id ); + } b_done = TRUE; } else if ( (current_events & LSCRIPTStateBitField[LSTT_REZ]) - &&(current_events & event_register)) + &&(current_events & event_register)) { for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData()) { @@ -449,17 +488,24 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL & data++; } // now, push any additional stack space - S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size; - lscript_pusharge(mBuffer, additional_size); - - // now set the bp correctly - sp = get_register(mBuffer, LREG_SP); - sp += additional_size + size; - set_bp(mBuffer, sp); - // set IP to the function - S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event); - set_ip(mBuffer, opcode_start); - mEventData.mEventDataList.deleteCurrentData(); + S32 additional_size = get_event_stack_size(mBuffer, current_state, event); + if ( additional_size == -1 ) + { // b_done will be set, so we'll exit the loop at the bottom + recordBoundaryError( id ); + } + else + { + additional_size -= size; + lscript_pusharge(mBuffer, additional_size); + + // now set the bp correctly + sp = get_register(mBuffer, LREG_SP); + sp += additional_size + size; + set_bp(mBuffer, sp); + // set IP to the function + setStateEventOpcoodeStartSafely( current_state, event, id ); + mEventData.mEventDataList.deleteCurrentData(); + } b_done = TRUE; break; } @@ -496,16 +542,23 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL & } b_done = TRUE; // now, push any additional stack space - S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size; - lscript_pusharge(mBuffer, additional_size); - - // now set the bp correctly - sp = get_register(mBuffer, LREG_SP); - sp += additional_size + size; - set_bp(mBuffer, sp); - // set IP to the function - S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event); - set_ip(mBuffer, opcode_start); + S32 additional_size = get_event_stack_size(mBuffer, current_state, event); + if ( additional_size == -1 ) + { // b_done was just set, so we'll exit the loop at the bottom + recordBoundaryError( id ); + } + else + { + additional_size -= size; + lscript_pusharge(mBuffer, additional_size); + + // now set the bp correctly + sp = get_register(mBuffer, LREG_SP); + sp += additional_size + size; + set_bp(mBuffer, sp); + // set IP to the function + setStateEventOpcoodeStartSafely( current_state, event, id ); + } } else { @@ -530,23 +583,30 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL & current_events &= ~LSCRIPTStateBitField[event]; set_event_register(mBuffer, LREG_CE, current_events, major_version); // now, push any additional stack space - S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size; - lscript_pusharge(mBuffer, additional_size); - - // now set the bp correctly - sp = get_register(mBuffer, LREG_SP); - sp += additional_size + size; - set_bp(mBuffer, sp); - // set IP to the function - S32 opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event); - set_ip(mBuffer, opcode_start); + S32 additional_size = get_event_stack_size(mBuffer, current_state, event); + if ( additional_size == -1 ) + { // b_done will be set, so we'll exit the loop at the bottom + recordBoundaryError( id ); + } + else + { + additional_size -= size; + lscript_pusharge(mBuffer, additional_size); + + // now set the bp correctly + sp = get_register(mBuffer, LREG_SP); + sp += additional_size + size; + set_bp(mBuffer, sp); + // set IP to the function + setStateEventOpcoodeStartSafely( current_state, event, id ); + } } b_done = TRUE; } - } + } // while (!b_done) + } // end of else ... in state processing code - return NO_DELETE_FLAG; - } + return NO_DELETE_FLAG; } BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id) |