Skip to content

Commit 8ceb5de

Browse files
fixing bug with ArrayConverter affecting other objects, better default
logErr, finishing and testing refactor of ObjectConverter, adding tests to GeneralExample
1 parent f4d8b06 commit 8ceb5de

File tree

13 files changed

+69
-551
lines changed

13 files changed

+69
-551
lines changed

SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,17 @@ public void logErr(Object obj, Throwable ex)
4040
throw new RuntimeException(obj.toString());
4141
throw new RuntimeException(ex);
4242
}
43-
System.err.println(obj);
43+
44+
try
45+
{
46+
StackTraceElement caller = Thread.currentThread().getStackTrace()[2];
47+
String callerName = caller.getClassName();
48+
System.err.println(callerName.substring(callerName.lastIndexOf('.')+1) + "#" + caller.getMethodName() + ": " + obj);
49+
}
50+
catch (Exception e)
51+
{
52+
System.err.println(obj);
53+
}
4454
}
4555

4656
/**

SerialX-core/src/main/java/org/ugp/serialx/Utils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ else if (objs[i] instanceof Class)
426426
}
427427

428428
for (int i = 0; i < classes.length; i++)
429-
classes[i] = objs[i].getClass();
429+
classes[i] = objs[i] == null ? Object.class : objs[i].getClass();
430430
return classes;
431431
}
432432

SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ public CharSequence toString(Object obj, Object... args)
260260
}
261261
}
262262

263-
LogProvider.instance.logErr(DataConverter.class.getSimpleName() + ": Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null);
263+
LogProvider.instance.logErr("Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null);
264264
return null;
265265
}
266266

@@ -316,7 +316,7 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class<?>[] ign
316316
if (returnAsStringIfNotFound)
317317
return str;
318318

319-
LogProvider.instance.logErr(DataParser.class.getSimpleName() + ": Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null);
319+
LogProvider.instance.logErr("Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null);
320320
return null;
321321
}
322322

SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
/**
2525
* This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions!
26-
* This is also responsible for {@link Scope}!
2726
* Its case sensitive!
2827
* <br>
2928
* <br>
@@ -48,14 +47,15 @@
4847
<td>10</td>
4948
</tr>
5049
</table>
51-
<br>
50+
Note: Be aware that invocation of static members such as functions and fields (:: operator) is disabled by default for the sake of security...<br>
51+
<br>
5252
This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).<br>
5353
This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).<br>
5454
* This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!</br>
5555
*
5656
* @author PETO
5757
*
58-
* @since 1.3.0
58+
* @since 1.3.0 (separated from ObjectConverter since 1.3.7)
5959
*/
6060
public class ProtocolConverter implements DataConverter
6161
{
@@ -71,6 +71,8 @@ public class ProtocolConverter implements DataConverter
7171
*/
7272
protected boolean useBase64IfCan = false;
7373

74+
protected boolean allowStaticMemberInvocation = false;
75+
7476
@Override
7577
public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs)
7678
{
@@ -99,11 +101,11 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile
99101
*/
100102
protected Object parse(ParserRegistry myHomeRegistry, Class<?> objClass, String str, Object... compilerArgs)
101103
{
102-
if (objClass == IsSelectorScope.class)
104+
if (objClass == IsSelectorScope.class) //Handle css-like selector scope to variable assignment
103105
{
104106
StringBuilder sb = new StringBuilder(str);
105107
sb.setCharAt(str.indexOf(' '), '=');
106-
return myHomeRegistry.parse(sb.toString(), compilerArgs);
108+
return myHomeRegistry.parse(sb.toString(), compilerArgs); //Should work only when ObjectConverter and VariableConverter are present...
107109
}
108110

109111
if (compilerArgs.length < 5)
@@ -116,6 +118,12 @@ protected Object parse(ParserRegistry myHomeRegistry, Class<?> objClass, String
116118
if (!isOneOf(args[0].charAt(0), '{', '[') && (nameIndex = args[0].indexOf("::")) > -1) //Is static member invocation
117119
{
118120
String memberName = args[0].substring(nameIndex + 2);
121+
if (!isAllowStaticMemberInvocation())
122+
{
123+
LogProvider.instance.logErr("Invocation of static member \"" + memberName + "\" from class \"" + objClass.getName() + "\" was denied because this feature is disabled by default for security reasons!", null);
124+
return null;
125+
}
126+
119127
if (args.length > 1)
120128
return InvokeStaticFunc(objClass, oldObjectClass, memberName, parseAll(myHomeRegistry, args, 1, true, compilerArgs), compilerArgs);
121129

@@ -274,6 +282,26 @@ public void setUseBase64IfCan(boolean useBase64IfCan)
274282
this.useBase64IfCan = useBase64IfCan;
275283
}
276284

285+
/**
286+
* @return True if invocation of static members (:: operator) is allowed (false by default)!
287+
*
288+
* @since 1.3.7
289+
*/
290+
public boolean isAllowStaticMemberInvocation()
291+
{
292+
return allowStaticMemberInvocation;
293+
}
294+
295+
/**
296+
* @param allowStaticMemberInvocation | Enable/disable the invocation of static members (:: operator) (false by default)!
297+
*
298+
* @since 1.3.7
299+
*/
300+
public void setAllowStaticMemberInvocation(boolean allowStaticMemberInvocation)
301+
{
302+
this.allowStaticMemberInvocation = allowStaticMemberInvocation;
303+
}
304+
277305
/**
278306
* @param obj | Object to get protocol for!
279307
* @param mode | Protocol mode!

SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public Map<Object, Object> unserialize(Class<? extends Map<Object, Object>> obje
3737
{
3838
boolean isFromScope = args.length == 1 && args[0] instanceof GenericScope;
3939
if (args.length % 2 != 0 && !isFromScope)
40-
LogProvider.instance.logErr(getClass().getSimpleName() + ": Some variables have no values, this is not good!", null);
40+
LogProvider.instance.logErr("Some variables have no values, this is not good!", null);
4141

4242
if (objectClass.isInterface())
4343
objectClass = (Class<? extends Map<Object, Object>>) HashMap.class;

SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public Object[] serialize(GenericScope<?, ?> object) throws Exception
2323
{
2424
if (object.getClass() != Scope.class)
2525
return new Object[] {object.castTo(Scope.class)};
26-
throw new UnsupportedOperationException(getClass().getSimpleName() + ": You are trying to serialize GenericScope or Scope via protocol! This is not good and should not even be possible! Scopes are meant to be serialized via converters!");
26+
throw new UnsupportedOperationException("You are trying to serialize GenericScope or Scope via protocol! This is not good and should not even be possible! Scopes are meant to be serialized via converters!");
2727
}
2828

2929
@Override

SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public abstract class SerializationProtocol<T>
3030
*
3131
* @since 1.3.0
3232
*/
33-
public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(new UniversalObjectInstantiationProtocol<>(Object.class), new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new SelfSerializableProtocol(), new EnumProtocol());
33+
public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(/*This might be unsafe: new UniversalObjectInstantiationProtocol<>(Object.class),*/ new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new SelfSerializableProtocol(), new EnumProtocol());
3434

3535
/**
3636
* This mode is for protocols that are used for serialization only!
@@ -191,7 +191,7 @@ public static <O> Object[] serializeObj(ProtocolRegistry registry, O object) thr
191191
SerializationProtocol<O> prot = registry.GetProtocolFor(object, MODE_SERIALIZE);
192192
if (prot == null)
193193
{
194-
LogProvider.instance.logErr(SerializationProtocol.class.getSimpleName() + ": Unable to serialize \"" + object + "\" because there is no registered and active protocol for serializing " + object.getClass() + "!", null);
194+
LogProvider.instance.logErr("Unable to serialize \"" + object + "\" because there is no registered and active protocol for serializing " + object.getClass() + "!", null);
195195
return null;
196196
}
197197
return prot.serialize(object);
@@ -231,7 +231,7 @@ public static <O> O unserializeObj(ProtocolRegistry registry, Class<? extends O>
231231
SerializationProtocol<O> prot = (SerializationProtocol<O>) registry.GetProtocolFor(objectClass, MODE_DESERIALIZE);
232232
if (prot == null)
233233
{
234-
LogProvider.instance.logErr(SerializationProtocol.class.getSimpleName() + ": Unable to unserialize " + Arrays.toString(args) + " because there is no registered and active protocol for unserializing \"" + objectClass + "\"!", null);
234+
LogProvider.instance.logErr("Unable to unserialize " + Arrays.toString(args) + " because there is no registered and active protocol for unserializing \"" + objectClass + "\"!", null);
235235
return null;
236236
}
237237
return (O) prot.unserialize(objectClass, args);
@@ -294,7 +294,7 @@ public ProtocolRegistry clone()
294294
public void add(int index, SerializationProtocol<?> element)
295295
{
296296
if (GetProtocolFor(element.applicableFor()) != null && element.applicableFor() != Object.class)
297-
LogProvider.instance.logErr(getClass().getSimpleName() + ": Protocol applicable for \"" + element.applicableFor().getName() + "\" is already registred!", null);
297+
LogProvider.instance.logErr("Protocol applicable for \"" + element.applicableFor().getName() + "\" is already registred!", null);
298298
addDuplicatively(index, element);
299299
}
300300

SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public UniversalObjectInstantiationProtocol(Class<T> applicableFor)
3333
@Override
3434
public Object[] serialize(T object)
3535
{
36-
throw new UnsupportedOperationException(getClass().getSimpleName() + ": This protocol is only for reading! It cant serialize " + object);
36+
throw new UnsupportedOperationException("This protocol is only for reading! It cant serialize " + object);
3737
}
3838

3939
@SuppressWarnings("unchecked")
@@ -54,7 +54,7 @@ public T unserialize(Class<? extends T> objectClass, Object... args) throws Exce
5454
catch (IllegalArgumentException e)
5555
{}
5656
}
57-
LogProvider.instance.logErr(getClass().getSimpleName() + ": Unable to call create new instance of \"" + objectClass + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied on any public constructor in required class!", null);
57+
LogProvider.instance.logErr("Unable to create new instance of \"" + objectClass + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied on any public constructor in required class!", null);
5858
return null;
5959
}
6060

SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public CharSequence toString(Object obj, Object... args) {
9494
}
9595
}
9696

97-
LogProvider.instance.logErr(DataConverter.class.getSimpleName() + ": Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null);
97+
LogProvider.instance.logErr("Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null);
9898
return null;
9999
}
100100

@@ -149,7 +149,7 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class<?>[] ign
149149
if (returnAsStringIfNotFound)
150150
return str;
151151

152-
LogProvider.instance.logErr(DataParser.class.getSimpleName() + ": Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null);
152+
LogProvider.instance.logErr("Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null);
153153
return null;
154154
}
155155

SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public class JussSerializer extends Serializer implements ImportsProvider
6363
*
6464
* @since 1.3.2
6565
*/
66-
public static final ParserRegistry JUSS_PARSERS = new ParserRegistry(new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter());
66+
public static final ParserRegistry JUSS_PARSERS = new ParserRegistry(new ImportConverter(), new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter());
6767

6868
/**
6969
* {@link ParserRegistry} with all parsers required to parse JUSS with additional operators.

SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,10 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object..
9797
tabs = (int) args[1];
9898

9999
if (args.length > 2)
100+
{
101+
args = args.clone(); //Necessary for preventing this from affecting other objects and arrays...
100102
args[2] = index + 1;
103+
}
101104

102105
Object[] elms = fromAmbiguousArray(obj);
103106
StringBuilder sb = new StringBuilder();

SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,17 @@
4242
<td>ArrayList 2 4 6</td>
4343
<td>new ArrayList<>(Arrays.asList(2, 4, 6))</td>
4444
</tr>
45+
<tr>
46+
<td>{ ... }</td>
47+
<td>new Scope( ... )</td>
48+
</tr>
4549
<tr>
4650
<td>java.lang.Math::max 10 5</td>
4751
<td>10</td>
4852
</tr>
4953
</table>
50-
<br>
54+
Note: Be aware that invocation of static members such as functions and fields (:: operator) is disabled by default for the sake of security...<br>
55+
<br>
5156
This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).<br>
5257
This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).<br>
5358
* This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!</br>
@@ -107,6 +112,8 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile
107112
}
108113

109114
//TODO: Prevent neccesity of scope parent inheritance.
115+
compilerArgs = compilerArgs.clone();
116+
compilerArgs[0] = false; //No extra formating...
110117
return str.isEmpty() ? scope : ((Serializer) scope/*.inheritParent()*/).LoadFrom(new StringReader(str), compilerArgs);
111118
}
112119
}

0 commit comments

Comments
 (0)