summaryrefslogtreecommitdiff
path: root/indra/lscript
diff options
context:
space:
mode:
authorDon Kjer <don@lindenlab.com>2007-09-28 23:32:53 +0000
committerDon Kjer <don@lindenlab.com>2007-09-28 23:32:53 +0000
commitb089fc559a5dc527ed5e0422e82abf3b1dd5f1b2 (patch)
treebaa68e98452406c03a3dbe21c99a901f769c8890 /indra/lscript
parentab8dd2b55008090a1f18fb107f897c736d98a760 (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.h41
-rw-r--r--indra/lscript/lscript_execute.h4
-rw-r--r--indra/lscript/lscript_execute/lscript_execute.cpp160
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)