mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-2809 Parse multiline string macro parameters used in WDM.h
This commit is contained in:
parent
0085e15971
commit
a70c2129cd
4 changed files with 100 additions and 23 deletions
|
@ -29,6 +29,8 @@ import ghidra.util.Msg;
|
|||
public class DefineTable {
|
||||
private static final String VARARG_ELLIPSIS = "...";
|
||||
|
||||
// the macro substitution could be done on a very large string, not just
|
||||
// a single line, Don't want it to go out of control replacing things
|
||||
private static final int ARBITRARY_MAX_REPLACEMENTS = 900000;
|
||||
|
||||
// Hastable for storing #defs
|
||||
|
@ -274,22 +276,32 @@ public class DefineTable {
|
|||
* @param pos position within string to start expanding
|
||||
* @return string with all substitutions applied
|
||||
*/
|
||||
private String macroSub(String image, int pos, ArrayList<String> sublist) {
|
||||
private String macroSub(String image, int pos, ArrayList<String> initialList) {
|
||||
int replaceCount = 0;
|
||||
|
||||
StringBuffer buf = new StringBuffer(image);
|
||||
int lastReplPos = pos;
|
||||
|
||||
boolean initialListSupplied = initialList != null; // initial list passed in
|
||||
ArrayList<String> sublist = new ArrayList<String>();
|
||||
if (initialList != null) {
|
||||
sublist.addAll(initialList);
|
||||
}
|
||||
|
||||
|
||||
// don't replace an infinite number of times. Fail safe for possible ininite loop
|
||||
while (pos < buf.length() && replaceCount < ARBITRARY_MAX_REPLACEMENTS) {
|
||||
// clear list of used macros when move past replacement area
|
||||
if (pos == lastReplPos) {
|
||||
sublist = new ArrayList<String>(); // ok to clear list of used macro names
|
||||
if (initialList != null) {
|
||||
sublist.addAll(initialList); // add back in initialList of nonreplacement names
|
||||
}
|
||||
}
|
||||
String defName = getDefineAt(buf, pos);
|
||||
if (shouldReplace(buf, defName, pos)) {
|
||||
// stop recursion on the same replacement string
|
||||
int replPos = replace(buf, defName, pos, sublist);
|
||||
int replPos = replace(buf, defName, pos, sublist, initialListSupplied);
|
||||
|
||||
if (replPos == -1) {
|
||||
// if no replacement string, move on
|
||||
|
@ -341,7 +353,7 @@ public class DefineTable {
|
|||
return true;
|
||||
}
|
||||
|
||||
int replace(StringBuffer buf, String currKey, int fromIndex, ArrayList<String> sublist) {
|
||||
int replace(StringBuffer buf, String currKey, int fromIndex, ArrayList<String> sublist, boolean initialList) {
|
||||
String replacementString = null;
|
||||
|
||||
if (sublist == null) {
|
||||
|
@ -375,7 +387,9 @@ public class DefineTable {
|
|||
Vector<PPToken> argv = getArgs(currKey);
|
||||
int replacedSubpieceLen = currKey.length();
|
||||
if (argv == null && sublist.contains(currKey)) {
|
||||
System.err.println("DONT Replace " + currKey + " in: " + buf);
|
||||
if (!initialList) {
|
||||
System.err.println("DONT Replace " + currKey + " in: " + buf);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (argv != null) {
|
||||
|
@ -613,7 +627,20 @@ public class DefineTable {
|
|||
* @return
|
||||
*/
|
||||
public String expand(String image, boolean join) {
|
||||
image = macroSub(image, 0, null);
|
||||
return expand(image, join, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* do the final expansion of "##" concats in the define strings that protect normal macro substitution.
|
||||
*
|
||||
* @param image
|
||||
* @param join
|
||||
* @param list of defines not to re-replace, stops recursive replacement on a define
|
||||
* @return
|
||||
*/
|
||||
public String expand(String image, boolean join, ArrayList<String> list) {
|
||||
|
||||
image = macroSub(image, 0, list);
|
||||
|
||||
// get rid of ## constructs
|
||||
if (join) {
|
||||
|
@ -760,7 +787,11 @@ public class DefineTable {
|
|||
// check if this is a numeric expression that could be simplified
|
||||
//
|
||||
String strValue = getValue(defName);
|
||||
String strExpanded = expand(strValue, true);
|
||||
|
||||
ArrayList<String> list = new ArrayList();
|
||||
list.add(defName);
|
||||
|
||||
String strExpanded = expand(strValue, true, list);
|
||||
strValue = strExpanded;
|
||||
|
||||
return strValue;
|
||||
|
|
|
@ -828,6 +828,13 @@ public class PreProcessor {
|
|||
println("False");
|
||||
return false;
|
||||
}
|
||||
|
||||
void bufAppendWithComment(PPToken buf, Token u) {
|
||||
if (emitExecSwitch==true)
|
||||
buf.append(u.image,true);
|
||||
else
|
||||
buf.append("//// " + u.image, false);
|
||||
}
|
||||
|
||||
// Parse include file
|
||||
private void includeFile(PPToken inc, boolean xsym) throws ParseException {
|
||||
|
@ -1863,23 +1870,28 @@ PPToken Text() :
|
|||
{Token u, nl, t = new Token(); PPToken buf = new PPToken(""); t.image="";}
|
||||
{
|
||||
( LOOKAHEAD(3)
|
||||
(LOOKAHEAD(2)(u=<OUTER_TEXT>{ if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false); }
|
||||
(LOOKAHEAD(2)nl=NewLines(){if (emitExecSwitch==true) buf.append(nl.image,true); else buf.append((u.image.length() == 0 ? "//// " : "") + nl.image, false); } )* |
|
||||
(LOOKAHEAD(2)(u=<OUTER_TEXT>{ bufAppendWithComment(buf,u); }
|
||||
(LOOKAHEAD(2)nl=NewLines() {if (emitExecSwitch==true) buf.append(nl.image,true); else buf.append((u.image.length() == 0 ? "//// " : "") + nl.image, false); } )* |
|
||||
|
||||
u=<OTHER_TEXT>{if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false); } )
|
||||
[LOOKAHEAD(2)u=NewLines(){ if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false); }]
|
||||
[LOOKAHEAD(2)u=QuotedText(){if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false);}]
|
||||
[LOOKAHEAD(2)u=<OTHER_TEXT>{if (emitExecSwitch==true) buf.append(u.image, true); else buf.append("//// " + u.image, false); }
|
||||
(LOOKAHEAD(2)u=NewLines(){ if (emitExecSwitch==true) buf.append(u.image, true); else buf.append("//// " + u.image, false);})*])+|
|
||||
u=<OTHER_TEXT> {bufAppendWithComment(buf,u); } )
|
||||
[LOOKAHEAD(2)u=NewLines() {bufAppendWithComment(buf,u); }]
|
||||
[(LOOKAHEAD(2)(u=QuotedText() {bufAppendWithComment(buf,u); }
|
||||
[LOOKAHEAD(2)u=NewLines(){ bufAppendWithComment(buf,u); }] |
|
||||
u=<OTHER_TEXT> {bufAppendWithComment(buf,u); })
|
||||
[LOOKAHEAD(2)t=NewLines() {if (emitExecSwitch==true) buf.append(t.image,true); else buf.append("//// " + u.image, false); }]
|
||||
[LOOKAHEAD(2)u=<OTHER_TEXT> {bufAppendWithComment(buf,u); }]
|
||||
[LOOKAHEAD(2)u=NewLines() {bufAppendWithComment(buf,u); }])+]
|
||||
[LOOKAHEAD(2)u=<OTHER_TEXT> {bufAppendWithComment(buf,u); }
|
||||
(LOOKAHEAD(2)u=NewLines(){ bufAppendWithComment(buf,u);})*])+|
|
||||
|
||||
(LOOKAHEAD(2)(u=QuotedText(){if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false); }
|
||||
[LOOKAHEAD(2)u=NewLines(){ if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false); }]|
|
||||
u=<OTHER_TEXT>{if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false); })
|
||||
[LOOKAHEAD(2)t=NewLines(){ if (emitExecSwitch==true) buf.append(t.image,true); else buf.append("//// " + u.image, false); }]
|
||||
[LOOKAHEAD(2)u=<OTHER_TEXT>{if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false); }]
|
||||
[LOOKAHEAD(2)u=NewLines(){ if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false); }])+ |
|
||||
(LOOKAHEAD(2)(u=QuotedText() {bufAppendWithComment(buf,u); }
|
||||
[LOOKAHEAD(2)u=NewLines(){ bufAppendWithComment(buf,u); }] |
|
||||
u=<OTHER_TEXT> {bufAppendWithComment(buf,u); })
|
||||
[LOOKAHEAD(2)t=NewLines() {if (emitExecSwitch==true) buf.append(t.image,true); else buf.append("//// " + u.image, false); }]
|
||||
[LOOKAHEAD(2)u=<OTHER_TEXT> {bufAppendWithComment(buf,u); }]
|
||||
[LOOKAHEAD(2)u=NewLines() {bufAppendWithComment(buf,u); }])+ |
|
||||
|
||||
u=NewLines(){ if (emitExecSwitch==true) buf.append(u.image,true); else buf.append("//// " + u.image, false); }
|
||||
u=NewLines() {bufAppendWithComment(buf,u); }
|
||||
) { return buf;}
|
||||
}
|
||||
|
||||
|
@ -1907,10 +1919,19 @@ PPToken NewLines() :
|
|||
}
|
||||
|
||||
PPToken QuotedText() :
|
||||
{Token u;}
|
||||
{Token t = null; Token r = null; }
|
||||
{
|
||||
(u=<QUOTED_TEXT>)
|
||||
{return new PPToken(u);}
|
||||
(t=<QUOTED_TEXT>
|
||||
{
|
||||
if (r == null) {
|
||||
r = t;
|
||||
} else {
|
||||
r.image = r.image.substring(0,r.image.length()) + t.image.substring(1);
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
||||
{ return new PPToken(r); }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -117,6 +117,16 @@ public class PreProcessorTest extends AbstractGenericTest {
|
|||
|
||||
assertTrue("Expanded protected macro with args", results.contains("int (getc)(FILE * );"));
|
||||
assertTrue("Expanded protected macro with args", results.contains("int (getchar)(void);"));
|
||||
|
||||
assertTrue("multi line string macro args failed ", results
|
||||
.indexOf("0x1 = multi_line_worked(\"Some text first line\"\n" +
|
||||
"\"More text second line\")") != -1);
|
||||
|
||||
assertTrue("multi line string macro args failed ", results
|
||||
.indexOf("D = dual_line_worked(2,\"Caution: First line\"\n" +
|
||||
"\" second line\"\n" +
|
||||
"\" third line\"\n" +
|
||||
"\" fourth line\")") != -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -498,5 +498,20 @@ int does_not_has_include();
|
|||
#define BEGINC QUOTED('"')
|
||||
#define TEST_QUOTED_QUOTE QUOTED('"')
|
||||
|
||||
#define TEST_MULTILINE_TEXT(t) multi_line_worked(t)
|
||||
|
||||
A = TEST_MULTILINE_TEXT("One Line")
|
||||
|
||||
B = TEST_MULTILINE_TEXT("Some text first line"
|
||||
"More text second line")
|
||||
|
||||
#define DUAL_MULTILINE(A, B) dual_line_worked(A,B)
|
||||
|
||||
C = DUAL_MULTILINE(1, OneLine("Caution: One Line"))
|
||||
|
||||
D = DUAL_MULTILINE(2, "Caution: First line"
|
||||
" second line"
|
||||
" third line"
|
||||
" fourth line")
|
||||
|
||||
theEnd();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue