diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScriptProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScriptProvider.java index d94e14cab1..82da554bf4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScriptProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScriptProvider.java @@ -148,4 +148,31 @@ public abstract class GhidraScriptProvider return scriptName; } + /** + * Return the start of certification header line if this file type is + * subject to certification. + * @return start of certification header or null if not supported + */ + protected String getCertifyHeaderStart() { + return null; + } + + /** + * Return the prefix for each certification header bofy line if + * this file is subject to certification + * @return certification heaber body prefix or null if not supported + */ + protected String getCertificationBodyPrefix() { + return null; + } + + /** + * Return the end of certification header line if this file type is + * subject to certification. + * @return end of certification header or null if not supported + */ + protected String getCertifyHeaderEnd() { + return null; + } + } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/JavaScriptProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/JavaScriptProvider.java index 39f99ffd91..8f3539576b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/script/JavaScriptProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/JavaScriptProvider.java @@ -164,6 +164,16 @@ public class JavaScriptProvider extends GhidraScriptProvider { return "//"; } + @Override + protected String getCertifyHeaderStart() { + return "/* ###"; + } + + @Override + protected String getCertifyHeaderEnd() { + return "*/"; + } + /** * * Fix script name for search in script directories, such as Java package parts in the name and inner class names. diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/ScriptInfo.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/ScriptInfo.java index 37c5e52016..f92c30647f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/script/ScriptInfo.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/ScriptInfo.java @@ -20,7 +20,6 @@ import static ghidra.util.HTMLUtilities.*; import java.io.*; import java.util.List; import java.util.StringTokenizer; -import java.util.regex.Pattern; import javax.swing.ImageIcon; import javax.swing.KeyStroke; @@ -47,9 +46,6 @@ public class ScriptInfo { static final String AT_MENUPATH = "@menupath"; static final String AT_TOOLBAR = "@toolbar"; - private static final Pattern DOCUMENTATION_START = Pattern.compile("/\\*"); - private static final Pattern DOCUMENTATION_END = Pattern.compile("\\*/"); - // omit from METADATA to avoid pre-populating in new scripts private static final String AT_IMPORTPACKAGE = "@importpackage"; @@ -186,6 +182,16 @@ public class ScriptInfo { init(); + String commentPrefix = provider.getCommentCharacter(); + + // Note that skipping certification header presumes that the header + // is intact with an appropriate start and end + String certifyHeaderStart = provider.getCertifyHeaderStart(); + String certifyHeaderEnd = provider.getCertifyHeaderEnd(); + String certifyHeaderBodyPrefix = provider.getCertificationBodyPrefix(); + boolean allowCertifyHeader = (certifyHeaderStart != null); + boolean skipCertifyHeader = false; + BufferedReader reader = null; try { StringBuffer buffer = new StringBuffer(); @@ -197,16 +203,34 @@ public class ScriptInfo { break; } - if (DOCUMENTATION_START.matcher(line).find()) { - while (line != null && !DOCUMENTATION_END.matcher(line).find()) { - line = reader.readLine(); + if (allowCertifyHeader) { + // Skip past certification header if found + if (skipCertifyHeader) { + String trimLine = line.trim(); + if (trimLine.startsWith(certifyHeaderEnd)) { + allowCertifyHeader = false; + skipCertifyHeader = false; + continue; + } + if (certifyHeaderBodyPrefix == null || + trimLine.startsWith(certifyHeaderBodyPrefix)) { + continue; // skip certification header body + } + // broken certification header - unexpected line + Msg.error(this, + "Script contains invalid certification header: " + getName()); + allowCertifyHeader = false; + skipCertifyHeader = false; + } + else if (line.startsWith(certifyHeaderStart)) { + skipCertifyHeader = true; + continue; } - continue; } - String commentPrefix = provider.getCommentCharacter(); - if (line.startsWith(commentPrefix)) { + allowCertifyHeader = false; + line = line.substring(commentPrefix.length()).trim(); if (line.startsWith("@")) { diff --git a/Ghidra/Features/Python/src/main/java/ghidra/python/PythonScriptProvider.java b/Ghidra/Features/Python/src/main/java/ghidra/python/PythonScriptProvider.java index cf5d5b29c7..7ccace6923 100644 --- a/Ghidra/Features/Python/src/main/java/ghidra/python/PythonScriptProvider.java +++ b/Ghidra/Features/Python/src/main/java/ghidra/python/PythonScriptProvider.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +15,12 @@ */ package ghidra.python; +import java.io.*; + import generic.jar.ResourceFile; import ghidra.app.script.GhidraScript; import ghidra.app.script.GhidraScriptProvider; -import java.io.*; - public class PythonScriptProvider extends GhidraScriptProvider { @Override @@ -39,6 +38,21 @@ public class PythonScriptProvider extends GhidraScriptProvider { return "#"; } + @Override + protected String getCertifyHeaderStart() { + return "## ###"; + } + + @Override + protected String getCertifyHeaderEnd() { + return "##"; + } + + @Override + protected String getCertificationBodyPrefix() { + return "#"; + } + @Override public String getDescription() { return "Python";