From: Alan M Webb <awebb@vnet.ibm.com>

This fixes a bug in LSL_Types.list GetSublist that was manifest if the
source list was empty and negative indices were used.
0.6.0-stable
Justin Clarke Casey 2008-04-16 15:57:55 +00:00
parent 4f8943da67
commit 9cb9dcb9da
1 changed files with 60 additions and 13 deletions

View File

@ -405,49 +405,96 @@ namespace OpenSim.Region.ScriptEngine.Common
public list GetSublist(int start, int end) public list GetSublist(int start, int end)
{ {
Console.WriteLine("GetSublist(" + start.ToString() + "," + end.ToString() + ")");
object[] ret; object[] ret;
// Take care of neg start or end's // Take care of neg start or end's
// NOTE that either index may still be negative after
// adding the length, so we must take additional
// measures to protect against this. Note also that
// after normalisation the negative indices are no
// longer relative to the end of the list.
if (start < 0) if (start < 0)
{ {
start = m_data.Length + start; start = m_data.Length + start;
} }
if (end < 0) if (end < 0)
{ {
end = m_data.Length + end; end = m_data.Length + end;
} }
// Case start <= end // The conventional case is start <= end
// NOTE that the case of an empty list is
// dealt with by the initial test. Start
// less than end is taken to be the most
// common case.
if (start <= end) if (start <= end)
{ {
if (start >= m_data.Length)
// Start sublist beyond length
// Also deals with start AND end still negative
if (start >= m_data.Length || end < 0)
{ {
return new list(); return new list();
} }
// Sublist extends beyond the end of the supplied list
if (end >= m_data.Length) if (end >= m_data.Length)
{ {
end = m_data.Length - 1; end = m_data.Length - 1;
} }
// Sublist still starts before the beginning of the list
if (start < 0)
{
start = 0;
}
ret = new object[end - start + 1]; ret = new object[end - start + 1];
Array.Copy(m_data, start, ret, 0, end - start + 1); Array.Copy(m_data, start, ret, 0, end - start + 1);
return new list(ret); return new list(ret);
} }
// Deal with the segmented case: 0->end + start->EOL
else else
{ {
if (start >= m_data.Length)
list result = null;
// If end is negative, then prefix list is empty
if(end < 0)
{ {
return GetSublist(0, end); result = new list();
// If start is still negative, then the whole of
// the existing list is returned. This case is
// only admitted if end is also still negative.
if(start < 0)
{
return this;
}
} }
if (end >= m_data.Length) else
{ {
return new list(); result = GetSublist(0,end);
} }
// end < start
//ret = new object[m_data.Length - Math.Abs(end - start + 1)]; // If start is outside of list, then just return
//Array.Copy(m_data, 0, ret, m_data.Length - start, end + 1); // the prefix, whatever it is.
//Array.Copy(m_data, start, ret, 0, m_data.Length - start); if(start >= m_data.Length)
return GetSublist(0, end) + GetSublist(start, Data.Length - 1); {
//return new list(ret); return result;
}
return result + GetSublist(start, Data.Length);
} }
} }