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} */