GP-2933 adding more error checking for theme.properties files

This commit is contained in:
ghidragon
2022-12-09 19:34:39 -05:00
parent bef76786bc
commit 1a99e2518d
10 changed files with 165 additions and 22 deletions
@@ -111,7 +111,7 @@ color.fg.listing.comment.auto = color.fg
color.fg.listing.comment.ref.repeatable = color.palette.darkcyan
color.fg.listing.function.callfixup = color.palette.magenta
color.fg.listing.function.param.dynamic = color.palette.teal
color.fg.listing.function.tag = color.palette.violetred
color.fg.listing.function.tag = #ff7090
color.fg.listing.label.primary = color.palette.cyan
color.fg.listing.mnemonic.override = color.palette.pink
@@ -172,8 +172,6 @@ font.plugin.tips.label = font.plugin.tips[BOLD]
[Dark Defaults]
color.bg = rgb(40, 42, 46) // TODO this should be in a more generic module
color.bg.undefined = #5C4D68
color.flowtype.fall.through = rgb(164, 66, 66)
@@ -71,6 +71,11 @@ src/main/doc/sleigh_common.xsl||GHIDRA||||END|
src/main/doc/sleigh_html.xsl||GHIDRA||||END|
src/main/doc/sleigh_pdf.xsl||GHIDRA||||END|
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/help/help/shared/arrow.gif||GHIDRA||reviewed||END|
src/main/help/help/shared/close16.gif||GHIDRA||||END|
src/main/help/help/shared/note.png||Oxygen Icons - LGPL 3.0||||END|
src/main/help/help/shared/note.yellow.png||Oxygen Icons - LGPL 3.0||||END|
src/main/help/help/shared/tip.png||Oxygen Icons - LGPL 3.0||||END|
src/main/help/help/topics/DecompilePlugin/DecompilerAnnotations.html||GHIDRA||||END|
src/main/help/help/topics/DecompilePlugin/DecompilerConcepts.html||GHIDRA||||END|
src/main/help/help/topics/DecompilePlugin/DecompilerIntro.html||GHIDRA||||END|
@@ -50,11 +50,8 @@ color.fg.decompiler.error = color.palette.red
color.fg.decompiler.variable = color.palette.olive
color.fg.decompiler.constant = color.palette.green
color.fg.decompiler.type = color.palette.cyan
color.fg.decompiler.parameter = color.palette.violetred
color.fg.decompiler.parameter = #ff7090
color.fg.decompiler.global = color.palette.teal
color.fg.decompiler.special = color.palette.red
color.bg.decompiler.middle.mouse = rgb(55,59,65)
color.bg.decompiler.current.variable = rgb(55, 59, 65)
@@ -10,6 +10,8 @@ color.palette.cornsilk = cornsilk
color.palette.crimson = crimson
color.palette.cyan = cyan
color.palette.darkblue = DarkBlue
color.palette.darkcyan = darkcyan
color.palette.darkgray = DarkGray
color.palette.darkgreen = darkgreen
color.palette.darkorange = darkorange
@@ -50,9 +52,9 @@ color.palette.silver = silver
color.palette.steelblue = steelblue
color.palette.tan = tan
color.palette.teal = teal
color.palette.white = white
color.palette.yellow = yellow
color.palette.yellowgreen = yellowgreen
color.palette.white = white
@@ -74,6 +76,5 @@ color.palette.yellow = #ffff80
color.palette.olive = #c0c080
color.palette.orange = #ffa070
color.palette.darkorange = orange
color.palette.violetred = #ff7090
@@ -224,7 +224,7 @@ color.fg.dialog.status.normal = lightBlue
color.bg.currentline = rgb(40,40,56) // dark bluish gray
color.cursor.focused = indianRed
color.cursor.unfocussed = darkGray
color.cursor.unfocused = darkGray
color.bg.textfield.hint.invalid = maroon
@@ -190,8 +190,15 @@ public abstract class AbstractThemeReader {
}
protected void error(int lineNumber, String message) {
String msg =
"Error parsing theme file \"" + source + "\" at line: " + lineNumber + ", " + message;
StringBuilder builder = new StringBuilder();
builder.append("Error parsing theme file \"" + source + "\"");
if (lineNumber >= 0) {
builder.append(" at line: " + lineNumber);
}
builder.append(". ");
builder.append(message);
String msg = builder.toString();
errors.add(msg);
outputError(msg);
}
@@ -317,4 +317,27 @@ public class GThemeValueMap {
}
}
/**
* Returns the set of all color ids in this map
* @return the set of all color ids in this map
*/
public Set<String> getColorIds() {
return colorMap.keySet();
}
/**
* Returns the set of all font ids in this map
* @return the set of all font ids in this map
*/
public Set<String> getFontIds() {
return fontMap.keySet();
}
/**
* Returns the set of all icon ids in this map
* @return the set of all icon ids in this map
*/
public Set<String> getIconIds() {
return iconMap.keySet();
}
}
@@ -26,9 +26,10 @@ import generic.jar.ResourceFile;
*/
public class ThemePropertyFileReader extends AbstractThemeReader {
private GThemeValueMap defaults;
private GThemeValueMap darkDefaults;
private GThemeValueMap defaults = new GThemeValueMap();
private GThemeValueMap darkDefaults = new GThemeValueMap();
private Map<LafType, GThemeValueMap> customSectionsMap = new HashMap<>();
private boolean defaultSectionProcessed;
/**
* Constructor for when the the theme.properties file is a {@link ResourceFile}
@@ -41,7 +42,6 @@ public class ThemePropertyFileReader extends AbstractThemeReader {
try (Reader reader = new InputStreamReader(file.getInputStream())) {
read(reader);
}
}
/**
@@ -60,7 +60,7 @@ public class ThemePropertyFileReader extends AbstractThemeReader {
* @return the map of standard defaults values.
*/
public GThemeValueMap getDefaultValues() {
return defaults == null ? new GThemeValueMap() : defaults;
return defaults;
}
/**
@@ -68,7 +68,7 @@ public class ThemePropertyFileReader extends AbstractThemeReader {
* @return the map of dark defaults values.
*/
public GThemeValueMap getDarkDefaultValues() {
return darkDefaults == null ? new GThemeValueMap() : darkDefaults;
return darkDefaults;
}
/**
@@ -81,20 +81,26 @@ public class ThemePropertyFileReader extends AbstractThemeReader {
protected void processNoSection(Section section) throws IOException {
if (!section.isEmpty()) {
error(0, "Theme properties file has values defined outside of a defined section");
error(section.getLineNumber(),
"Theme properties file has values defined outside of a defined section");
}
}
@Override
protected void processDefaultSection(Section section) throws IOException {
defaults = new GThemeValueMap();
defaultSectionProcessed = true;
processValues(defaults, section);
}
@Override
protected void processDarkDefaultSection(Section section) throws IOException {
darkDefaults = new GThemeValueMap();
if (!defaultSectionProcessed) {
error(section.getLineNumber(),
"Defaults section must be defined before Dark Defaults section!");
return;
}
processValues(darkDefaults, section);
validate("Dark Defaults", darkDefaults);
}
@Override
@@ -102,11 +108,42 @@ public class ThemePropertyFileReader extends AbstractThemeReader {
String name = section.getName();
LafType lafType = LafType.fromName(name);
if (lafType == null) {
error(0, "Unknown Look and Feel section found: " + name);
error(section.getLineNumber(), "Unknown Look and Feel section found: " + name);
return;
}
if (!defaultSectionProcessed) {
error(section.getLineNumber(),
"Defaults section must be defined before " + name + " section!");
return;
}
GThemeValueMap customValues = new GThemeValueMap();
processValues(customValues, section);
customSectionsMap.put(lafType, customValues);
validate(name, customValues);
}
private void validate(String name, GThemeValueMap valuesMap) {
for (String id : valuesMap.getColorIds()) {
if (!defaults.containsColor(id)) {
reportMissingDefaultsError("Color", name, id);
}
}
for (String id : valuesMap.getFontIds()) {
if (!defaults.containsFont(id)) {
reportMissingDefaultsError("Font", name, id);
}
}
for (String id : valuesMap.getIconIds()) {
if (!defaults.containsIcon(id)) {
reportMissingDefaultsError("Icon", name, id);
}
}
}
private void reportMissingDefaultsError(String type, String name, String id) {
String message = type + " id found in \"" + name +
"\" section, but not defined in \"Defaults\" section: " + id;
error(-1, message);
}
}
@@ -91,6 +91,14 @@ public class ThemePropertyFileReaderTest {
public void testDarkDefaults() throws IOException {
//@formatter:off
ThemePropertyFileReader reader = new ThemePropertyFileReader("test", new StringReader(String.join("\n",
"[Defaults]",
" color.b.1 = red",
" color.b.2 = red",
" color.b.3 = red",
" color.b.4 = red",
" color.b.5 = red",
" color.b.6 = red",
" color.b.7 = red",
"[Dark Defaults]",
" color.b.1 = white", // WHITE
" color.b.2 = #ff0000", // RED
@@ -189,7 +197,7 @@ public class ThemePropertyFileReaderTest {
List<String> errors = reader.getErrors();
assertEquals(1, errors.size());
assertEquals(
"Error parsing theme file \"test\" at line: 3, Could not parse Color value: sdfsdf",
"Error parsing theme file \"test\" at line: 3. Could not parse Color value: sdfsdf",
errors.get(0));
}
@@ -236,6 +244,73 @@ public class ThemePropertyFileReaderTest {
}
@Test
public void testColorIdDefinedInNonDefaultsSectionOnly() throws IOException {
//@formatter:off
ThemePropertyFileReader reader = new SilentThemePropertyFileReader("test", new StringReader(String.join("\n",
"[Defaults]",
" color.foo = red",
"[Dark Defaults]",
" color.bar = blue",
"")));
//@formatter:on
List<String> errors = reader.getErrors();
assertEquals(1, errors.size());
assertEquals(
"Error parsing theme file \"test\". Color id found in \"Dark Defaults\" section, but not defined in \"Defaults\" section: color.bar",
errors.get(0));
}
@Test
public void testFontIdDefinedInNonDefaultsSectionOnly() throws IOException {
//@formatter:off
ThemePropertyFileReader reader = new SilentThemePropertyFileReader("test", new StringReader(String.join("\n",
"[Defaults]",
"[Dark Defaults]",
" font.bar = dialog-PLAIN-14",
"")));
//@formatter:on
List<String> errors = reader.getErrors();
assertEquals(1, errors.size());
assertEquals(
"Error parsing theme file \"test\". Font id found in \"Dark Defaults\" section, but not defined in \"Defaults\" section: font.bar",
errors.get(0));
}
@Test
public void testIconIdDefinedInNonDefaultsSectionOnly() throws IOException {
//@formatter:off
ThemePropertyFileReader reader = new SilentThemePropertyFileReader("test", new StringReader(String.join("\n",
"[Defaults]",
"[Dark Defaults]",
" icon.bar = core.png",
"")));
//@formatter:on
List<String> errors = reader.getErrors();
assertEquals(1, errors.size());
assertEquals(
"Error parsing theme file \"test\". Icon id found in \"Dark Defaults\" section, but not defined in \"Defaults\" section: icon.bar",
errors.get(0));
}
@Test
public void testDefaultSectionMustBeFirst() throws Exception {
//@formatter:off
ThemePropertyFileReader reader = new SilentThemePropertyFileReader("test", new StringReader(String.join("\n",
"[Dark Defaults]",
" color.foo = red",
"[Defaults]",
" color.bar = blue",
"")));
//@formatter:on
List<String> errors = reader.getErrors();
assertEquals(1, errors.size());
assertEquals(
"Error parsing theme file \"test\" at line: 1. Defaults section must be defined before Dark Defaults section!",
errors.get(0));
}
private Color getColor(GThemeValueMap values, String id) {
ColorValue color = values.getColor(id);
return color.get(values);