You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/11/02 14:38:12 UTC
[3/3] ignite git commit: IGNITE-1418: Fixed potential schema leak.
IGNITE-1418: Fixed potential schema leak.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0fa9fb94
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0fa9fb94
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0fa9fb94
Branch: refs/heads/ignite-1814-debug
Commit: 0fa9fb9452effc3402b34936d37b0e4485791381
Parents: 15fa7ab
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Mon Nov 2 16:38:51 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Nov 2 16:38:51 2015 +0300
----------------------------------------------------------------------
.../portable/PortableClassDescriptor.java | 33 ++-
.../internal/portable/PortableWriterExImpl.java | 30 ++-
.../portable/builder/PortableBuilderImpl.java | 248 +++++++++----------
3 files changed, 170 insertions(+), 141 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0fa9fb94/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
index 9f7f0c6..aa72017 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
@@ -524,12 +524,17 @@ public class PortableClassDescriptor {
case PORTABLE:
if (writeHeader(obj, writer)) {
- if (serializer != null)
- serializer.writePortable(obj, writer);
- else
- ((PortableMarshalAware)obj).writePortable(writer);
+ try {
+ if (serializer != null)
+ serializer.writePortable(obj, writer);
+ else
+ ((PortableMarshalAware) obj).writePortable(writer);
- writer.postWrite(userType);
+ writer.postWrite(userType);
+ }
+ finally {
+ writer.popSchema();
+ }
if (obj.getClass() != PortableMetaDataImpl.class
&& ctx.isMetaDataChanged(typeId, writer.metaDataHashSum())) {
@@ -552,22 +557,30 @@ public class PortableClassDescriptor {
try {
((Externalizable)obj).writeExternal(writer);
+
+ writer.postWrite(userType);
}
catch (IOException e) {
throw new PortableException("Failed to write Externalizable object: " + obj, e);
}
-
- writer.postWrite(userType);
+ finally {
+ writer.popSchema();
+ }
}
break;
case OBJECT:
if (writeHeader(obj, writer)) {
- for (FieldInfo info : fields)
- info.write(obj, writer);
+ try {
+ for (FieldInfo info : fields)
+ info.write(obj, writer);
- writer.postWrite(userType);
+ writer.postWrite(userType);
+ }
+ finally {
+ writer.popSchema();
+ }
}
break;
http://git-wip-us.apache.org/repos/asf/ignite/blob/0fa9fb94/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
index 42426d9..ff85ecd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java
@@ -348,7 +348,7 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
out.writeInt(start + SCHEMA_OR_RAW_OFF_POS, out.position() - start);
// Write the schema.
- int offsetByteCnt = schema.writeAndPop(this, fieldCnt);
+ int offsetByteCnt = schema.write(this, fieldCnt);
// Write raw offset if needed.
if (rawOffPos != 0)
@@ -380,6 +380,17 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
}
/**
+ * Pop schema.
+ */
+ public void popSchema() {
+ if (schema != null) {
+ assert fieldCnt > 0;
+
+ schema.pop(fieldCnt);
+ }
+ }
+
+ /**
* @param val Byte array.
*/
public void write(byte[] val) {
@@ -1850,11 +1861,11 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
* Write collected frames and pop them.
*
* @param writer Writer.
- * @param cnt Count.
+ * @param fieldCnt Count.
* @return Amount of bytes dedicated to
*/
- public int writeAndPop(PortableWriterExImpl writer, int cnt) {
- int startIdx = idx - cnt * 2;
+ public int write(PortableWriterExImpl writer, int fieldCnt) {
+ int startIdx = idx - fieldCnt * 2;
assert startIdx >= 0;
@@ -1887,13 +1898,18 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx
res = PortableUtils.OFFSET_4;
}
- idx = startIdx;
+ return res;
+ }
+
+ /**
+ * Pop current object's frame.
+ */
+ public void pop(int fieldCnt) {
+ idx = idx - fieldCnt * 2;
// Shrink data array if needed.
if (idx == 0 && data.length > MAX_SIZE)
data = new int[MAX_SIZE];
-
- return res;
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0fa9fb94/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
index 4edb792..608425d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
@@ -202,188 +202,188 @@ public class PortableBuilderImpl implements PortableBuilder {
* @param serializer Serializer.
*/
void serializeTo(PortableWriterExImpl writer, PortableBuilderSerializer serializer) {
- PortableUtils.writeHeader(writer,
- true,
- registeredType ? typeId : UNREGISTERED_TYPE_ID,
- hashCode,
- registeredType ? null : clsNameToWrite);
+ try {
+ PortableUtils.writeHeader(writer,
+ true,
+ registeredType ? typeId : UNREGISTERED_TYPE_ID,
+ hashCode,
+ registeredType ? null : clsNameToWrite);
- Set<Integer> remainsFlds = null;
+ Set<Integer> remainsFlds = null;
- if (reader != null) {
- Map<Integer, Object> assignedFldsById;
+ if (reader != null) {
+ Map<Integer, Object> assignedFldsById;
- if (assignedVals != null) {
- assignedFldsById = U.newHashMap(assignedVals.size());
+ if (assignedVals != null) {
+ assignedFldsById = U.newHashMap(assignedVals.size());
- for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
- int fldId = ctx.fieldId(typeId, entry.getKey());
+ for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
+ int fldId = ctx.fieldId(typeId, entry.getKey());
- assignedFldsById.put(fldId, entry.getValue());
- }
+ assignedFldsById.put(fldId, entry.getValue());
+ }
- remainsFlds = assignedFldsById.keySet();
- }
- else
- assignedFldsById = Collections.emptyMap();
+ remainsFlds = assignedFldsById.keySet();
+ } else
+ assignedFldsById = Collections.emptyMap();
- // Get footer details.
- int fieldOffsetSize = PortableUtils.fieldOffsetSize(flags);
+ // Get footer details.
+ int fieldOffsetSize = PortableUtils.fieldOffsetSize(flags);
- IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(reader, start, fieldOffsetSize);
+ IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(reader, start, fieldOffsetSize);
- int footerPos = footer.get1();
- int footerEnd = footer.get2();
+ int footerPos = footer.get1();
+ int footerEnd = footer.get2();
- // Get raw position.
- int rawPos = PortableUtils.rawOffsetAbsolute(reader, start, fieldOffsetSize);
+ // Get raw position.
+ int rawPos = PortableUtils.rawOffsetAbsolute(reader, start, fieldOffsetSize);
- // Position reader on data.
- reader.position(start + hdrLen);
+ // Position reader on data.
+ reader.position(start + hdrLen);
- while (reader.position() + 4 < rawPos) {
- int fieldId = reader.readIntPositioned(footerPos);
- int fieldLen = fieldPositionAndLength(footerPos, footerEnd, rawPos, fieldOffsetSize).get2();
+ while (reader.position() + 4 < rawPos) {
+ int fieldId = reader.readIntPositioned(footerPos);
+ int fieldLen = fieldPositionAndLength(footerPos, footerEnd, rawPos, fieldOffsetSize).get2();
- footerPos += 4 + fieldOffsetSize;
+ footerPos += 4 + fieldOffsetSize;
- if (assignedFldsById.containsKey(fieldId)) {
- Object assignedVal = assignedFldsById.remove(fieldId);
+ if (assignedFldsById.containsKey(fieldId)) {
+ Object assignedVal = assignedFldsById.remove(fieldId);
- reader.skip(fieldLen);
+ reader.skip(fieldLen);
- if (assignedVal != REMOVED_FIELD_MARKER) {
- writer.writeFieldId(fieldId);
+ if (assignedVal != REMOVED_FIELD_MARKER) {
+ writer.writeFieldId(fieldId);
- serializer.writeValue(writer, assignedVal);
- }
- }
- else {
- int type = fieldLen != 0 ? reader.readByte(0) : 0;
+ serializer.writeValue(writer, assignedVal);
+ }
+ } else {
+ int type = fieldLen != 0 ? reader.readByte(0) : 0;
- if (fieldLen != 0 && !PortableUtils.isPlainArrayType(type) && PortableUtils.isPlainType(type)) {
- writer.writeFieldId(fieldId);
- writer.write(reader.array(), reader.position(), fieldLen);
+ if (fieldLen != 0 && !PortableUtils.isPlainArrayType(type) && PortableUtils.isPlainType(type)) {
+ writer.writeFieldId(fieldId);
+ writer.write(reader.array(), reader.position(), fieldLen);
- reader.skip(fieldLen);
- }
- else {
- writer.writeFieldId(fieldId);
+ reader.skip(fieldLen);
+ } else {
+ writer.writeFieldId(fieldId);
- Object val;
+ Object val;
- if (fieldLen == 0)
- val = null;
- else if (readCache == null) {
- int savedPos = reader.position();
+ if (fieldLen == 0)
+ val = null;
+ else if (readCache == null) {
+ int savedPos = reader.position();
- val = reader.parseValue();
+ val = reader.parseValue();
- assert reader.position() == savedPos + fieldLen;
- }
- else {
- val = readCache.get(fieldId);
+ assert reader.position() == savedPos + fieldLen;
+ } else {
+ val = readCache.get(fieldId);
- reader.skip(fieldLen);
- }
+ reader.skip(fieldLen);
+ }
- serializer.writeValue(writer, val);
+ serializer.writeValue(writer, val);
+ }
}
}
}
- }
-
- if (assignedVals != null && (remainsFlds == null || !remainsFlds.isEmpty())) {
- boolean metadataEnabled = ctx.isMetaDataEnabled(typeId);
- PortableMetadata metadata = null;
+ if (assignedVals != null && (remainsFlds == null || !remainsFlds.isEmpty())) {
+ boolean metadataEnabled = ctx.isMetaDataEnabled(typeId);
- if (metadataEnabled)
- metadata = ctx.metaData(typeId);
+ PortableMetadata metadata = null;
- Map<String, String> newFldsMetadata = null;
+ if (metadataEnabled)
+ metadata = ctx.metaData(typeId);
- for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
- Object val = entry.getValue();
+ Map<String, String> newFldsMetadata = null;
- if (val == REMOVED_FIELD_MARKER)
- continue;
-
- String name = entry.getKey();
+ for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
+ Object val = entry.getValue();
- int fldId = ctx.fieldId(typeId, name);
+ if (val == REMOVED_FIELD_MARKER)
+ continue;
- if (remainsFlds != null && !remainsFlds.contains(fldId))
- continue;
+ String name = entry.getKey();
- writer.writeFieldId(fldId);
+ int fldId = ctx.fieldId(typeId, name);
- serializer.writeValue(writer, val);
+ if (remainsFlds != null && !remainsFlds.contains(fldId))
+ continue;
- if (metadataEnabled) {
- String oldFldTypeName = metadata == null ? null : metadata.fieldTypeName(name);
+ writer.writeFieldId(fldId);
- String newFldTypeName;
+ serializer.writeValue(writer, val);
- if (val instanceof PortableValueWithType)
- newFldTypeName = ((PortableValueWithType)val).typeName();
- else {
- byte type = PortableUtils.typeByClass(val.getClass());
+ if (metadataEnabled) {
+ String oldFldTypeName = metadata == null ? null : metadata.fieldTypeName(name);
- newFldTypeName = CacheObjectPortableProcessorImpl.fieldTypeName(type);
- }
+ String newFldTypeName;
- if (oldFldTypeName == null) {
- // It's a new field, we have to add it to metadata.
+ if (val instanceof PortableValueWithType)
+ newFldTypeName = ((PortableValueWithType) val).typeName();
+ else {
+ byte type = PortableUtils.typeByClass(val.getClass());
- if (newFldsMetadata == null)
- newFldsMetadata = new HashMap<>();
+ newFldTypeName = CacheObjectPortableProcessorImpl.fieldTypeName(type);
+ }
- newFldsMetadata.put(name, newFldTypeName);
- }
- else {
- if (!"Object".equals(oldFldTypeName) && !oldFldTypeName.equals(newFldTypeName)) {
- throw new PortableException(
- "Wrong value has been set [" +
- "typeName=" + (typeName == null ? metadata.typeName() : typeName) +
- ", fieldName=" + name +
- ", fieldType=" + oldFldTypeName +
- ", assignedValueType=" + newFldTypeName +
- ", assignedValue=" + (((PortableValueWithType)val).value()) + ']'
- );
+ if (oldFldTypeName == null) {
+ // It's a new field, we have to add it to metadata.
+
+ if (newFldsMetadata == null)
+ newFldsMetadata = new HashMap<>();
+
+ newFldsMetadata.put(name, newFldTypeName);
+ } else {
+ if (!"Object".equals(oldFldTypeName) && !oldFldTypeName.equals(newFldTypeName)) {
+ throw new PortableException(
+ "Wrong value has been set [" +
+ "typeName=" + (typeName == null ? metadata.typeName() : typeName) +
+ ", fieldName=" + name +
+ ", fieldType=" + oldFldTypeName +
+ ", assignedValueType=" + newFldTypeName +
+ ", assignedValue=" + (((PortableValueWithType) val).value()) + ']'
+ );
+ }
}
}
}
- }
- if (newFldsMetadata != null) {
- String typeName = this.typeName;
+ if (newFldsMetadata != null) {
+ String typeName = this.typeName;
- if (typeName == null)
- typeName = metadata.typeName();
+ if (typeName == null)
+ typeName = metadata.typeName();
- ctx.updateMetaData(typeId, typeName, newFldsMetadata);
+ ctx.updateMetaData(typeId, typeName, newFldsMetadata);
+ }
}
- }
- if (reader != null) {
- // Write raw data if any.
- int fieldOffsetSize = PortableUtils.fieldOffsetSize(flags);
+ if (reader != null) {
+ // Write raw data if any.
+ int fieldOffsetSize = PortableUtils.fieldOffsetSize(flags);
- int rawOff = PortableUtils.rawOffsetAbsolute(reader, start, fieldOffsetSize);
- int footerStart = PortableUtils.footerStartAbsolute(reader, start);
+ int rawOff = PortableUtils.rawOffsetAbsolute(reader, start, fieldOffsetSize);
+ int footerStart = PortableUtils.footerStartAbsolute(reader, start);
- if (rawOff < footerStart) {
- writer.rawWriter();
+ if (rawOff < footerStart) {
+ writer.rawWriter();
- writer.write(reader.array(), rawOff, footerStart - rawOff);
+ writer.write(reader.array(), rawOff, footerStart - rawOff);
+ }
+
+ // Shift reader to the end of the object.
+ reader.position(start + PortableUtils.length(reader, start));
}
- // Shift reader to the end of the object.
- reader.position(start + PortableUtils.length(reader, start));
+ writer.postWrite(true);
+ }
+ finally {
+ writer.popSchema();
}
-
- writer.postWrite(true);
}
/** {@inheritDoc} */