CommandHelper

CommandHelper

46.5k Downloads

ArrayIndexOutOfBoundsException in while().

LadyCailinBot opened this issue · 3 comments

commented

CMDHELPER-2887 - Reported by CyaNox

Not exactly sure if this is my fault or not (still have to investigate my code) but the following error should probably have better handling:

root@qubetubers:/srv/mc/scripts/sk89q# java -jar CommandHelper.jar cmdline nbttest.ms
TAGTYPE: 10
TAGNAME:
TAGTYPE: 10
TAGNAME: data
TAGTYPE: 3
TAGNAME: Tick
Jan 16, 2014 12:42:55 AM com.laytonsmith.core.Script eval
SEVERE: Uh oh! You've found an error in MethodScript. This is an error caused by your code, so you may be able to find a workaround, but is ultimately an error in MethodScript itself. The line of code that caused the error was this:
while()
on or around /srv/mc/scripts/sk89q/NBT.inc.ms:55.
Please report this error to the developers, and be sure to include the version numbers: Server version: SHELL; MethodScript version: 3.3.1-SNAPSHOT:2522-a8e1e6c,master. Here's the stacktrace:
java.lang.ArrayIndexOutOfBoundsException: 1
        at com.laytonsmith.core.functions.DataHandling$_while.execs(DataHandling.java:796)
        at com.laytonsmith.core.Script.eval(Script.java:260)
        at com.laytonsmith.core.Script.eval(Script.java:270)
        at com.laytonsmith.core.Script.seval(Script.java:208)
        at com.laytonsmith.core.functions.BasicLogic$_switch.execs(BasicLogic.java:277)
        at com.laytonsmith.core.Script.eval(Script.java:260)
        at com.laytonsmith.core.Procedure.execute(Procedure.java:194)
        at com.laytonsmith.core.Procedure.cexecute(Procedure.java:149)
        at com.laytonsmith.core.Script.eval(Script.java:237)
        at com.laytonsmith.core.Script.eval(Script.java:270)
        at com.laytonsmith.core.Procedure.execute(Procedure.java:191)
        at com.laytonsmith.core.Procedure.cexecute(Procedure.java:149)
        at com.laytonsmith.core.Script.eval(Script.java:237)
        at com.laytonsmith.core.Script.seval(Script.java:208)
        at com.laytonsmith.core.functions.DataHandling$_while.execs(DataHandling.java:794)
        at com.laytonsmith.core.Script.eval(Script.java:260)
        at com.laytonsmith.core.Script.eval(Script.java:270)
        at com.laytonsmith.core.Script.seval(Script.java:208)
        at com.laytonsmith.core.functions.BasicLogic$_switch.execs(BasicLogic.java:277)
        at com.laytonsmith.core.Script.eval(Script.java:260)
        at com.laytonsmith.core.Procedure.execute(Procedure.java:194)
        at com.laytonsmith.core.Procedure.cexecute(Procedure.java:149)
        at com.laytonsmith.core.Script.eval(Script.java:237)
        at com.laytonsmith.core.Script.eval(Script.java:270)
        at com.laytonsmith.core.Procedure.execute(Procedure.java:191)
        at com.laytonsmith.core.Procedure.cexecute(Procedure.java:149)
        at com.laytonsmith.core.Script.eval(Script.java:237)
        at com.laytonsmith.core.Procedure.execute(Procedure.java:191)
        at com.laytonsmith.core.Procedure.cexecute(Procedure.java:149)
        at com.laytonsmith.core.Script.eval(Script.java:237)
        at com.laytonsmith.core.Script.eval(Script.java:270)
        at com.laytonsmith.core.Script.eval(Script.java:270)
        at com.laytonsmith.core.MethodScriptCompiler.execute(MethodScriptCompiler.java:1592)
        at com.laytonsmith.tools.Interpreter.execute(Interpreter.java:255)
        at com.laytonsmith.tools.Interpreter.startWithTTY(Interpreter.java:87)
        at com.laytonsmith.core.Main.main(Main.java:349)

The code that produced it:

{code:title=nbttest.ms}
include('NBT.inc.ms')

console(_NBT_read('villages'))

{code:title=NBT.inc.ms}
/*****************************************************************************\
| ©opyright 2013 Mark Sanders (CyaNox) All Rights Reserved                    |
\*****************************************************************************/

proc(_NBT_read, @filename){
  @ba = string_get_bytes(read(@filename))
  ba_rewind(@ba)
  @tree = array()
  _NBT_traverseTag(@ba, @tree)
  return(@tree)
}

proc(_NBT_traverseTag, @ba, @tree){
  @tagtype = _NBT_readType(@ba, 1)
  if (@tagtype == 0){
    return(false)
  }
  @tagname = _NBT_readType(@ba, 8)
  @tagdata = _NBT_readType(@ba, @tagtype)
  @tree[] = array('type': @tagtype, 'name': @tagname, 'value': @tagdata)
  return(true)
}

proc(_NBT_readType, @ba, @type){
  switch(@type){
    1,
      return(ba_get_byte(@ba)),
    2,
      return(ba_get_short(@ba)),
    3,
      return(ba_get_int(@ba)),
    4,
      return(ba_get_long(@ba)),
    5,
      return(ba_get_float(@ba)),
    6,
      return(ba_get_double(@ba)),
    7,
      @length = ba_get_int(@ba)
      return(ba_get_bytes(@ba, @length)),
    8,
      return(ba_get_string(@ba)),
    9,
      @tagid = ba_get_byte(@ba)
      @length = ba_get_int(@ba)
      @list = array('type': @tagid, 'value': array())
      for(@i = 0, @i < @length, @i++){
        @list['value'][] = _NBT_readType(@ba, @tagid)
      }
      return(@list),
    10,
      @tree = array()
      while(_NBT_traverseTag(@ba, @tree))
      return(@tree),
    11,
      @length = ba_get_int(@ba)
      @list = array('type': 3, 'value': array())
      for(@i = 0, @i < @length, @i++){
        @list['value'][] = _NBT_readType(@ba, @tagid)
      }
      return(@list),
  }
}
commented

Comment by CyaNox

I believe this was caused by the while loop without "code" body.

Doing:

while(_NBT_traverseTag(@ba, @tree), g())

works around this issue.

commented

Comment by LadyCailin

After considering it, I'll allow for while to provide an empty code element.

commented

Comment by LadyCailin

This will be allowed in the next version.