diff --git a/src/main/java/de/rwth/idsg/steve/ocpp/ws/JsonObjectMapper.java b/src/main/java/de/rwth/idsg/steve/ocpp/ws/JsonObjectMapper.java index 26d54d867..a379eb629 100644 --- a/src/main/java/de/rwth/idsg/steve/ocpp/ws/JsonObjectMapper.java +++ b/src/main/java/de/rwth/idsg/steve/ocpp/ws/JsonObjectMapper.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.annotation.JsonInclude; import de.rwth.idsg.ocpp.jaxb.validation.BeanValidationModule; -import de.rwth.idsg.steve.ocpp.ws.custom.CustomStringModule; import de.rwth.idsg.steve.ocpp.ws.ocpp12.Ocpp12JacksonModule; import de.rwth.idsg.steve.ocpp.ws.ocpp15.Ocpp15JacksonModule; import de.rwth.idsg.steve.ocpp.ws.ocpp16.Ocpp16JacksonModule; @@ -59,7 +58,6 @@ public enum JsonObjectMapper { .enable(FAIL_ON_NULL_FOR_PRIMITIVES) .enable(WRITE_BIGDECIMAL_AS_PLAIN) .disable(FAIL_ON_UNKNOWN_PROPERTIES) - .addModule(new CustomStringModule()) .addModule(new Ocpp12JacksonModule()) .addModule(new Ocpp15JacksonModule()) .addModule(new Ocpp16JacksonModule()) diff --git a/src/main/java/de/rwth/idsg/steve/ocpp/ws/custom/CustomStringModule.java b/src/main/java/de/rwth/idsg/steve/ocpp/ws/custom/CustomStringModule.java deleted file mode 100644 index 61ab38de3..000000000 --- a/src/main/java/de/rwth/idsg/steve/ocpp/ws/custom/CustomStringModule.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SteVe - SteckdosenVerwaltung - https://github.com/steve-community/steve - * Copyright (C) 2013-2026 SteVe Community Team - * All Rights Reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package de.rwth.idsg.steve.ocpp.ws.custom; - -import org.owasp.encoder.Encode; -import tools.jackson.core.JacksonException; -import tools.jackson.core.JsonGenerator; -import tools.jackson.core.JsonParser; -import tools.jackson.core.Version; -import tools.jackson.databind.DatabindException; -import tools.jackson.databind.DeserializationContext; -import tools.jackson.databind.JavaType; -import tools.jackson.databind.SerializationContext; -import tools.jackson.databind.deser.jdk.StringDeserializer; -import tools.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; -import tools.jackson.databind.jsontype.TypeSerializer; -import tools.jackson.databind.module.SimpleModule; -import tools.jackson.databind.ser.jdk.StringSerializer; -import tools.jackson.databind.ser.std.StdScalarSerializer; - -/** - * @author Sevket Goekay - * @since 17.08.2022 - */ -public class CustomStringModule extends SimpleModule { - - public CustomStringModule() { - super("CustomStringModule", new Version(0, 0, 1, null, "de.rwth.idsg", "steve")); - - super.addSerializer(String.class, new CustomStringSerializer()); - super.addDeserializer(String.class, new CustomStringDeserializer()); - } - - /** - * Since {@link StringSerializer} is marked as final, its contents are copied here (and adjusted as needed). - */ - private static class CustomStringSerializer extends StdScalarSerializer { - - public CustomStringSerializer() { - super(String.class, false); - } - - @Override - public boolean isEmpty(SerializationContext prov, Object value) { - String str = (String) value; - return str.isEmpty(); - } - - @Override - public void serialize(Object value, JsonGenerator gen, SerializationContext provider) throws JacksonException { - gen.writeString(objectToString(value)); - } - - @Override - public final void serializeWithType(Object value, JsonGenerator gen, SerializationContext provider, - TypeSerializer typeSer) throws JacksonException { - gen.writeString(objectToString(value)); - } - - @Override - public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws DatabindException { - visitStringFormat(visitor, typeHint); - } - - private static String objectToString(Object value) { - return Encode.forHtml((String) value); - } - } - - private static class CustomStringDeserializer extends StringDeserializer { - - @Override - public String deserialize(JsonParser p, DeserializationContext ctxt) throws JacksonException { - String val = super.deserialize(p, ctxt); - return Encode.forHtml(val); - } - } -} diff --git a/src/test/java/de/rwth/idsg/steve/ocpp/ws/custom/CustomStringModuleTest.java b/src/test/java/de/rwth/idsg/steve/ocpp/ws/custom/CustomStringModuleTest.java index 7cbb9ce46..671b75c98 100644 --- a/src/test/java/de/rwth/idsg/steve/ocpp/ws/custom/CustomStringModuleTest.java +++ b/src/test/java/de/rwth/idsg/steve/ocpp/ws/custom/CustomStringModuleTest.java @@ -25,6 +25,10 @@ import org.junit.jupiter.api.Test; /** + * Verifies that the Jackson ObjectMapper does not HTML-encode string values. + * Strings must be serialized using standard JSON escaping (RFC 8259) so that + * OCPP wire payloads are not corrupted. + * * @author Sevket Goekay * @since 17.08.2022 */ @@ -43,14 +47,40 @@ public void testNormalString() throws Exception { public void testLink() throws Exception { SimpleJsonModel input = new SimpleJsonModel("Some link"); String output = mapper.writeValueAsString(input); - Assertions.assertEquals("{\"someText\":\"<a href="link">Some link</a>\"}", output); + // Standard JSON escaping: quotes inside strings are escaped with backslash, + // angle brackets are passed through unmodified (no HTML encoding). + Assertions.assertEquals("{\"someText\":\"Some link\"}", output); } @Test public void testScript() throws Exception { SimpleJsonModel input = new SimpleJsonModel(""; + SimpleJsonModel input = new SimpleJsonModel(original); + String json = mapper.writeValueAsString(input); + SimpleJsonModel deserialized = mapper.readValue(json, SimpleJsonModel.class); + Assertions.assertEquals(original, deserialized.getSomeText()); } @Data