Skip to content

Commit b11bb2b

Browse files
jcschaffclaude
andcommitted
Validate entity names against invalid XML chars
Wire XmlChars.requireValidAttributeContent into TokenMangler.checkNameProperty (used by BioModel, MathModel, Simulation, SimulationContext, Structure name vetos) and into ReactionStep.vetoableChange("name"). Allows whitespace but rejects C0 control chars and U+FFFD, so that bad chars from external sources can't reach the VCML attribute payload via setName. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6b52e92 commit b11bb2b

2 files changed

Lines changed: 19 additions & 6 deletions

File tree

vcell-core/src/main/java/cbit/vcell/model/ReactionStep.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.vcell.util.IssueContext.ContextType;
2929
import org.vcell.util.document.Identifiable;
3030
import org.vcell.util.document.KeyValue;
31+
import org.vcell.util.xml.XmlChars;
3132

3233
import cbit.vcell.model.Kinetics.KineticsParameter;
3334
import cbit.vcell.model.Membrane.MembraneVoltage;
@@ -1065,7 +1066,7 @@ public void setSbmlId(String newValue) throws PropertyVetoException{
10651066

10661067
public void setSbmlName(String newString) throws PropertyVetoException{
10671068
String oldValue = this.sbmlName;
1068-
String newValue = SpeciesContext.fixSbmlName(newString);
1069+
String newValue = SpeciesContext.fixAndValidateSbmlName(newString, this);
10691070

10701071
fireVetoableChange("sbmlName", oldValue, newValue);
10711072
this.sbmlName = newValue;
@@ -1167,6 +1168,11 @@ public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException{
11671168
if(((String) (e.getNewValue())).trim().length() > 255){
11681169
throw new PropertyVetoException("reactionStep name for reaction \'" + (String) (e.getNewValue()) + "\' cannot be longer than 255 characters", e);
11691170
}
1171+
try {
1172+
XmlChars.requireValidAttributeContent((String) e.getNewValue(), "Reaction.name");
1173+
} catch (IllegalArgumentException ex) {
1174+
throw new PropertyVetoException(ex.getMessage(), e);
1175+
}
11701176
}
11711177
if(e.getSource() == this && e.getPropertyName().equals("chargeCarrierValence")){
11721178
if((e.getNewValue() != null) && ((Integer) (e.getNewValue())).intValue() != 0){

vcell-util/src/main/java/org/vcell/util/TokenMangler.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
package org.vcell.util;
1212

13+
import org.vcell.util.xml.XmlChars;
14+
1315
import java.beans.PropertyChangeEvent;
1416
import java.beans.PropertyVetoException;
1517

@@ -453,12 +455,17 @@ public static void checkLoginID(String loginID) throws IllegalArgumentException
453455
*/
454456
public static void checkNameProperty(Object source, String owner, PropertyChangeEvent evt) throws PropertyVetoException {
455457
if (evt.getSource() == source && evt.getPropertyName().equals("name") && evt.getNewValue()!=null){
456-
if (evt.getNewValue() == null || ((String)evt.getNewValue()).trim().length()==0){
458+
String newName = (String) evt.getNewValue();
459+
if (newName.trim().length()==0){
457460
throw new PropertyVetoException("A name must be given to save " + owner + "s", evt);
458-
}
459-
// else if (((String)evt.getNewValue()).contains("'")){
460-
// throw new PropertyVetoException("Apostrophe is not allowed in " + owner + " names",evt);
461-
// }
461+
}
462+
try {
463+
// allow whitespace (entity names like BioModel may contain spaces)
464+
// but reject control characters and U+FFFD
465+
XmlChars.requireValidAttributeContent(newName, owner + ".name");
466+
} catch (IllegalArgumentException ex) {
467+
throw new PropertyVetoException(ex.getMessage(), evt);
468+
}
462469
}
463470
}
464471

0 commit comments

Comments
 (0)