Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions user/src/com/google/gwt/user/RemoteService.gwt.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@
-->
<define-configuration-property name="rpc.enhancedClasses" is-multi-valued="true"/>

<!--
Controls whether RPC generates support for server-enhanced classes. Set
this to false to ignore both JPA/JDO annotations and the
rpc.enhancedClasses list, preventing @ClientFields entries and the
corresponding client-side payload handling from being generated, and so
preventing the server from seeing JPA/JDO fields returned to it from
client calls.

This remains enabled by default for backwards compatibility. The server
separately refuses serialization policies with enhanced classes unless
the application explicitly enables them at runtime.
-->
<define-configuration-property name="rpc.enhancedClasses.enabled"
is-multi-valued="false"/>
<set-configuration-property name="rpc.enhancedClasses.enabled" value="true"/>

<generate-with class="com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator">
<when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/>
</generate-with>
Expand Down
11 changes: 10 additions & 1 deletion user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ public class ProxyCreator {
*/
public static final String CACHED_PROPERTY_INFO_KEY = "cached-property-info";
public static final String CACHED_TYPE_INFO_KEY = "cached-type-info";
static final String CACHED_ENHANCED_CLASSES_PROPERTY_INFO_KEY =
"cached-enhanced-classes-property-info";

/**
* The directory within which RPC manifests are placed for individual
Expand All @@ -103,7 +105,10 @@ public class ProxyCreator {
* Properties which need to be checked to determine cache reusability.
*/
private static final Collection<String> configPropsToCheck = Arrays.asList(
TypeSerializerCreator.GWT_ELIDE_TYPE_NAMES_FROM_RPC, Shared.RPC_ENHANCED_CLASSES);
TypeSerializerCreator.GWT_ELIDE_TYPE_NAMES_FROM_RPC, Shared.RPC_ENHANCED_CLASSES,
Shared.RPC_ENHANCED_CLASSES_ENABLED);
private static final Collection<String> enhancedClassesConfigPropsToCheck =
Arrays.asList(Shared.RPC_ENHANCED_CLASSES, Shared.RPC_ENHANCED_CLASSES_ENABLED);
private static final Collection<String> selectionPropsToCheck = Arrays
.asList(Shared.RPC_PROP_SUPPRESS_NON_STATIC_FINAL_FIELD_WARNINGS);

Expand Down Expand Up @@ -396,8 +401,12 @@ public RebindResult create(TreeLogger logger, GeneratorContext context)
CachedPropertyInformation cpi =
new CachedPropertyInformation(logger, context.getPropertyOracle(), selectionPropsToCheck,
configPropsToCheck);
CachedPropertyInformation enhancedClassesCpi =
new CachedPropertyInformation(logger, context.getPropertyOracle(), null,
enhancedClassesConfigPropsToCheck);
result.putClientData(CACHED_TYPE_INFO_KEY, cti);
result.putClientData(CACHED_PROPERTY_INFO_KEY, cpi);
result.putClientData(CACHED_ENHANCED_CLASSES_PROPERTY_INFO_KEY, enhancedClassesCpi);

return result;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@
* </pre>
*
* <p>
* Enhanced class handling can be disabled entirely, including the automatic detection of JDO and
* JPA annotations, by setting the following configuration property:
*
* <pre>
* <set-configuration-property name='rpc.enhancedClasses.enabled' value='false'/>
* </pre>
*
* <p>
* Enhanced classes are checked for the presence of additional serializable
* fields on the server that were not defined in client code as seen by the GWT
* compiler. If it is possible for an instance of such a class to be transmitted
Expand Down Expand Up @@ -694,6 +702,8 @@ private static void logSerializableTypes(TreeLogger logger, Set<JClassType> fiel

private final GeneratorContext context;

private final boolean enhancedClassesEnabled;

private Set<String> enhancedClasses = null;

private PrintWriter logOutputWriter;
Expand Down Expand Up @@ -751,6 +761,8 @@ public SerializableTypeOracleBuilder(TreeLogger logger, GeneratorContext context
}

enhancedClasses = Shared.getEnhancedTypes(context.getPropertyOracle());
enhancedClassesEnabled =
Shared.shouldEnableEnhancedClasses(logger, context.getPropertyOracle());
}

public void addRootType(TreeLogger logger, JType type) {
Expand Down Expand Up @@ -867,8 +879,10 @@ public SerializableTypeOracle build(TreeLogger logger) throws UnableToCompleteEx
fieldSerializableTypes.add(type);
}

if (tic.maybeEnhanced()
|| (enhancedClasses != null && enhancedClasses.contains(type.getQualifiedSourceName()))) {
if (enhancedClassesEnabled
&& (tic.maybeEnhanced()
|| (enhancedClasses != null
&& enhancedClasses.contains(type.getQualifiedSourceName())))) {
logger.log(TreeLogger.WARN, "The class " + type.getQualifiedSourceName() + " has " +
"JPA/JDO annotations or is explicitly configured as an enhanced class using the " +
"configuration property rpc.enhancedClasses. This makes the server vulnerable " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class ServiceInterfaceProxyGenerator extends IncrementalGenerator {
* generator results will be invalidated automatically if they were generated
* by a version of this generator with a different version id.
*/
private static final long GENERATOR_VERSION_ID = 1L;
private static final long GENERATOR_VERSION_ID = 2L;

@Override
public RebindResult generateIncrementally(TreeLogger logger, GeneratorContext ctx,
Expand Down
35 changes: 35 additions & 0 deletions user/src/com/google/gwt/user/rebind/rpc/Shared.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class Shared {
*/
public static final String RPC_ENHANCED_CLASSES = "rpc.enhancedClasses";

/**
* Single-valued configuration property used to disable all enhanced class handling at compile
* time.
*/
public static final String RPC_ENHANCED_CLASSES_ENABLED = "rpc.enhancedClasses.enabled";

/**
* Capitalizes a name.
*
Expand Down Expand Up @@ -80,6 +86,35 @@ static Set<String> getEnhancedTypes(PropertyOracle propertyOracle) {
}
}

/**
* Returns whether RPC should generate support for server-enhanced classes.
*
* @param propertyOracle the property oracle used to access the relevant configuration property
* @return whether enhanced class handling is enabled
*/
static boolean shouldEnableEnhancedClasses(TreeLogger logger, PropertyOracle propertyOracle) {
try {
ConfigurationProperty prop =
propertyOracle.getConfigurationProperty(RPC_ENHANCED_CLASSES_ENABLED);
if (prop.getValues().size() == 1) {
String value = prop.getValues().get(0);
if ("true".equalsIgnoreCase(value)) {
return true;
}
if ("false".equalsIgnoreCase(value)) {
return false;
}
}
Comment thread
niloc132 marked this conversation as resolved.
} catch (BadPropertyValueException e) {
// Warn below and retain the backwards-compatible behavior.
}

logger.log(TreeLogger.WARN, "The configuration property " + RPC_ENHANCED_CLASSES_ENABLED
+ " was missing or did not have exactly one 'true' or 'false' value. Is "
+ "RemoteService.gwt.xml inherited? Enhanced class support will remain enabled.");
return true;
}

static String getStreamReadMethodNameFor(JType type) {
return "read" + getCallSuffix(type);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.core.ext.BadPropertyValueException;
import com.google.gwt.core.ext.CachedGeneratorResult;
import com.google.gwt.core.ext.CachedPropertyInformation;
import com.google.gwt.core.ext.ConfigurationProperty;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
Expand Down Expand Up @@ -114,6 +115,8 @@ private static void computeShardSize(TreeLogger logger) throws UnableToCompleteE

private final boolean elideTypeNames;

private final boolean canReuseCachedFieldSerializers;

private final JType[] serializableTypes;

private final SerializableTypeOracle serializationOracle;
Expand Down Expand Up @@ -170,9 +173,12 @@ public TypeSerializerCreator(TreeLogger logger, SerializableTypeOracle serializa
}

if (context.isGeneratorResultCachingEnabled()) {
canReuseCachedFieldSerializers =
cachedEnhancedClassesConfigurationMatches(logger, context);
typesNotUsingCustomFieldSerializers = new HashSet<JType>();
customFieldSerializersUsed = new HashSet<JType>();
} else {
canReuseCachedFieldSerializers = false;
typesNotUsingCustomFieldSerializers = null;
customFieldSerializersUsed = null;
}
Expand Down Expand Up @@ -303,6 +309,10 @@ private void createFieldSerializers(TreeLogger logger, GeneratorContext ctx) {
private boolean findReusableCachedFieldSerializerIfAvailable(TreeLogger logger,
GeneratorContext ctx, JType type, JType customFieldSerializer) {

if (!canReuseCachedFieldSerializers) {
return false;
}

CachedGeneratorResult lastResult = ctx.getCachedGeneratorResult();
if (lastResult == null || !ctx.isGeneratorResultCachingEnabled()) {
return false;
Expand Down Expand Up @@ -352,6 +362,20 @@ private boolean findReusableCachedFieldSerializerIfAvailable(TreeLogger logger,
return foundMatch;
}

static boolean cachedEnhancedClassesConfigurationMatches(TreeLogger logger,
GeneratorContext context) {
CachedGeneratorResult lastResult = context.getCachedGeneratorResult();
if (lastResult == null || !context.isGeneratorResultCachingEnabled()) {
return false;
}

CachedPropertyInformation cpi =
(CachedPropertyInformation) lastResult.getClientData(
ProxyCreator.CACHED_ENHANCED_CLASSES_PROPERTY_INFO_KEY);
return cpi != null
&& cpi.checkPropertiesWithPropertyOracle(logger, context.getPropertyOracle());
}

private String[] getPackageAndClassName(String fullClassName) {
String className = fullClassName;
String packageName = "";
Expand Down Expand Up @@ -849,4 +873,3 @@ private void writeTypeMethodsNative(JType type) {
srcWriter.outdent();
}
}

Loading