show error message when offset is too large

This commit is contained in:
2015-05-02 20:21:36 +02:00
parent 37647545ec
commit 913b3f22e3
3 changed files with 88 additions and 16 deletions
@@ -153,11 +153,15 @@ public class SWFOutputStream extends OutputStream {
/**
* Writes UI8 (Unsigned 8bit integer) value to the stream
*
* @param val UI8 value to write
* @param value UI8 value to write
* @throws IOException
*/
public void writeUI8(int val) throws IOException {
write(val);
public void writeUI8(int value) throws IOException {
if (value > 0xff) {
throw new Error("Value is too large for UI8: " + value);
}
write(value);
}
/**
@@ -167,7 +171,14 @@ public class SWFOutputStream extends OutputStream {
* @throws IOException
*/
public void writeString(String value) throws IOException {
write(Utf8Helper.getBytes(value));
byte[] data = Utf8Helper.getBytes(value);
for (int i = 0; i < data.length; i++) {
if (data[i] == 0) {
throw new IOException("String should not contain null character.");
}
}
write(data);
write(0);
}
@@ -178,6 +189,10 @@ public class SWFOutputStream extends OutputStream {
* @throws IOException
*/
public void writeUI32(long value) throws IOException {
if (value > 0xffffffffL) {
throw new Error("Value is too large for UI32: " + value);
}
write((int) (value & 0xff));
write((int) ((value >> 8) & 0xff));
write((int) ((value >> 16) & 0xff));
@@ -191,6 +206,10 @@ public class SWFOutputStream extends OutputStream {
* @throws IOException
*/
public void writeUI16(int value) throws IOException {
if (value > 0xffff) {
throw new Error("Value is too large for UI16: " + value);
}
write((int) (value & 0xff));
write((int) ((value >> 8) & 0xff));
}
@@ -202,6 +221,10 @@ public class SWFOutputStream extends OutputStream {
* @throws IOException
*/
public void writeSI32(long value) throws IOException {
if (value > 0x7fffffffL) {
throw new Error("Value is too large for SI32: " + value);
}
writeUI32(value);
}
@@ -212,6 +235,10 @@ public class SWFOutputStream extends OutputStream {
* @throws IOException
*/
public void writeSI16(int value) throws IOException {
if (value > 0x7fff) {
throw new Error("Value is too large for SI16: " + value);
}
writeUI16(value);
}
@@ -222,6 +249,10 @@ public class SWFOutputStream extends OutputStream {
* @throws IOException
*/
public void writeSI8(int value) throws IOException {
if (value > 0x7ff) {
throw new Error("Value is too large for SI8: " + value);
}
writeUI8(value);
}
@@ -1,16 +1,16 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
@@ -1,16 +1,16 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
package com.jpexs.decompiler.flash.action.parser.pcode;
@@ -128,14 +128,16 @@ import com.jpexs.helpers.Helper;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ASMParser {
public static ActionList parse(boolean ignoreNops, List<Label> labels, long address, FlasmLexer lexer, List<String> constantPool, int version) throws IOException, ActionParseException {
public static ActionList parse(boolean ignoreNops, List<Label> labels, Map<Action, Integer> lineMap, long address, FlasmLexer lexer, List<String> constantPool, int version) throws IOException, ActionParseException {
ActionList list = new ActionList();
Stack<GraphSourceItemContainer> containers = new Stack<>();
@@ -192,6 +194,7 @@ public class ASMParser {
}
if (a != null) {
list.add(a);
lineMap.put(a, lexer.yyline());
}
} else if (symb.type == ASMParsedSymbol.TYPE_EOL) {
} else if ((symb.type == ASMParsedSymbol.TYPE_BLOCK_END) || (symb.type == ASMParsedSymbol.TYPE_EOF)) {
@@ -464,7 +467,8 @@ public class ASMParser {
lexer = new FlasmLexer(new StringReader(source));
List<Label> labels = new ArrayList<>();
ActionList ret = parse(ignoreNops, labels, address, lexer, constantPool, version);
Map<Action, Integer> lineMap = new HashMap<>();
ActionList ret = parse(ignoreNops, labels, lineMap, address, lexer, constantPool, version);
//Action.setActionsAddresses(ret, address, version);
for (Action link : ret) {
if (!(link instanceof ActionIf || link instanceof ActionJump)) {
@@ -480,7 +484,22 @@ public class ASMParser {
ActionJump actionJump = (ActionJump) link;
if (actionJump.identifier.equals(label.name)) {
actionJump.setJumpOffset((int) (label.address - (actionJump.getAddress() + actionJump.getTotalActionLength())));
int offset = (int) (label.address - (actionJump.getAddress() + actionJump.getTotalActionLength()));
if (offset < -0x8000 || offset > 0x7fff) {
String message = "Jump offset is too large:" + offset + " addr: ofs" + Helper.formatAddress(link.getAddress());
if (throwOnError) {
Integer line = lineMap.get(link);
if (line == null) {
line = -1;
}
throw new ActionParseException(message, line);
} else {
Logger.getLogger(ASMParser.class.getName()).log(Level.SEVERE, message);
}
}
actionJump.setJumpOffset(offset);
found = true;
break;
}
@@ -491,7 +510,22 @@ public class ASMParser {
for (Label label : labels) {
if (actionIf.identifier.equals(label.name)) {
actionIf.setJumpOffset((int) (label.address - (actionIf.getAddress() + actionIf.getTotalActionLength())));
int offset = (int) (label.address - (actionIf.getAddress() + actionIf.getTotalActionLength()));
if (offset < -0x8000 || offset > 0x7fff) {
String message = "If offset is too large:" + offset + " addr: ofs" + Helper.formatAddress(link.getAddress());
if (throwOnError) {
Integer line = lineMap.get(link);
if (line == null) {
line = -1;
}
throw new ActionParseException(message, line);
} else {
Logger.getLogger(ASMParser.class.getName()).log(Level.SEVERE, message);
}
}
actionIf.setJumpOffset(offset);
found = true;
break;
}
@@ -499,13 +533,20 @@ public class ASMParser {
}
if (!found) {
String message = "TARGET NOT FOUND - identifier:" + identifier + " addr: ofs" + Helper.formatAddress(link.getAddress());
if (throwOnError) {
throw new ActionParseException("TARGET NOT FOUND - identifier:" + identifier + " addr: ofs" + Helper.formatAddress(link.getAddress()), -1);
Integer line = lineMap.get(link);
if (line == null) {
line = -1;
}
throw new ActionParseException(message, line);
} else {
Logger.getLogger(ASMParser.class.getName()).log(Level.SEVERE, "TARGET NOT FOUND - identifier:" + identifier + " addr: ofs" + Helper.formatAddress(link.getAddress()));
Logger.getLogger(ASMParser.class.getName()).log(Level.SEVERE, message);
}
}
}
return ret;
}
}