diff options
author | Justin Clarke Casey | 2008-04-16 15:57:55 +0000 |
---|---|---|
committer | Justin Clarke Casey | 2008-04-16 15:57:55 +0000 |
commit | 9cb9dcb9dada7eaae18a16bcc77e4cdfa470f112 (patch) | |
tree | 0bf6395f54e4f5359745dbd9d842241da31b0c50 | |
parent | * From Kurt Taylor <krtaylor@us.ibm.com> (diff) | |
download | opensim-SC_OLD-9cb9dcb9dada7eaae18a16bcc77e4cdfa470f112.zip opensim-SC_OLD-9cb9dcb9dada7eaae18a16bcc77e4cdfa470f112.tar.gz opensim-SC_OLD-9cb9dcb9dada7eaae18a16bcc77e4cdfa470f112.tar.bz2 opensim-SC_OLD-9cb9dcb9dada7eaae18a16bcc77e4cdfa470f112.tar.xz |
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.
-rw-r--r-- | OpenSim/Region/ScriptEngine/Common/LSL_Types.cs | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs index 292950c..55c13a4 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs | |||
@@ -405,49 +405,96 @@ namespace OpenSim.Region.ScriptEngine.Common | |||
405 | 405 | ||
406 | public list GetSublist(int start, int end) | 406 | public list GetSublist(int start, int end) |
407 | { | 407 | { |
408 | Console.WriteLine("GetSublist(" + start.ToString() + "," + end.ToString() + ")"); | 408 | |
409 | object[] ret; | 409 | object[] ret; |
410 | |||
410 | // Take care of neg start or end's | 411 | // Take care of neg start or end's |
412 | // NOTE that either index may still be negative after | ||
413 | // adding the length, so we must take additional | ||
414 | // measures to protect against this. Note also that | ||
415 | // after normalisation the negative indices are no | ||
416 | // longer relative to the end of the list. | ||
417 | |||
411 | if (start < 0) | 418 | if (start < 0) |
412 | { | 419 | { |
413 | start = m_data.Length + start; | 420 | start = m_data.Length + start; |
414 | } | 421 | } |
422 | |||
415 | if (end < 0) | 423 | if (end < 0) |
416 | { | 424 | { |
417 | end = m_data.Length + end; | 425 | end = m_data.Length + end; |
418 | } | 426 | } |
419 | 427 | ||
420 | // Case start <= end | 428 | // The conventional case is start <= end |
429 | // NOTE that the case of an empty list is | ||
430 | // dealt with by the initial test. Start | ||
431 | // less than end is taken to be the most | ||
432 | // common case. | ||
433 | |||
421 | if (start <= end) | 434 | if (start <= end) |
422 | { | 435 | { |
423 | if (start >= m_data.Length) | 436 | |
437 | // Start sublist beyond length | ||
438 | // Also deals with start AND end still negative | ||
439 | if (start >= m_data.Length || end < 0) | ||
424 | { | 440 | { |
425 | return new list(); | 441 | return new list(); |
426 | } | 442 | } |
443 | |||
444 | // Sublist extends beyond the end of the supplied list | ||
427 | if (end >= m_data.Length) | 445 | if (end >= m_data.Length) |
428 | { | 446 | { |
429 | end = m_data.Length - 1; | 447 | end = m_data.Length - 1; |
430 | } | 448 | } |
449 | |||
450 | // Sublist still starts before the beginning of the list | ||
451 | if (start < 0) | ||
452 | { | ||
453 | start = 0; | ||
454 | } | ||
455 | |||
431 | ret = new object[end - start + 1]; | 456 | ret = new object[end - start + 1]; |
457 | |||
432 | Array.Copy(m_data, start, ret, 0, end - start + 1); | 458 | Array.Copy(m_data, start, ret, 0, end - start + 1); |
459 | |||
433 | return new list(ret); | 460 | return new list(ret); |
461 | |||
434 | } | 462 | } |
463 | |||
464 | // Deal with the segmented case: 0->end + start->EOL | ||
465 | |||
435 | else | 466 | else |
436 | { | 467 | { |
437 | if (start >= m_data.Length) | 468 | |
469 | list result = null; | ||
470 | |||
471 | // If end is negative, then prefix list is empty | ||
472 | if(end < 0) | ||
438 | { | 473 | { |
439 | return GetSublist(0, end); | 474 | result = new list(); |
475 | // If start is still negative, then the whole of | ||
476 | // the existing list is returned. This case is | ||
477 | // only admitted if end is also still negative. | ||
478 | if(start < 0) | ||
479 | { | ||
480 | return this; | ||
481 | } | ||
482 | |||
440 | } | 483 | } |
441 | if (end >= m_data.Length) | 484 | else |
442 | { | 485 | { |
443 | return new list(); | 486 | result = GetSublist(0,end); |
487 | } | ||
488 | |||
489 | // If start is outside of list, then just return | ||
490 | // the prefix, whatever it is. | ||
491 | if(start >= m_data.Length) | ||
492 | { | ||
493 | return result; | ||
444 | } | 494 | } |
445 | // end < start | 495 | |
446 | //ret = new object[m_data.Length - Math.Abs(end - start + 1)]; | 496 | return result + GetSublist(start, Data.Length); |
447 | //Array.Copy(m_data, 0, ret, m_data.Length - start, end + 1); | 497 | |
448 | //Array.Copy(m_data, start, ret, 0, m_data.Length - start); | ||
449 | return GetSublist(0, end) + GetSublist(start, Data.Length - 1); | ||
450 | //return new list(ret); | ||
451 | } | 498 | } |
452 | } | 499 | } |
453 | 500 | ||