[Mono-bugs] [Bug 404128] New: Error in SoapFormatter

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Thu Jun 26 10:35:44 EDT 2008


https://bugzilla.novell.com/show_bug.cgi?id=404128


           Summary: Error in SoapFormatter
           Product: Mono: Class Libraries
           Version: SVN
          Platform: i686
        OS/Version: Windows Vista
            Status: NEW
          Severity: Blocker
          Priority: P5 - None
         Component: System
        AssignedTo: mono-bugs at lists.ximian.com
        ReportedBy: migelU at gmail.com
         QAContact: mono-bugs at lists.ximian.com
          Found By: Development


SoapFormatter badly deserialize SOAP message with custom header
Here is my test program:
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Soap;

namespace SoapFormatterTest
{
        internal static class Constants
        {
                public const string ContentType = "Content-Type";
                public const string HeaderArgs = "__Args";
                public const string HeaderCallContext = "__CallContext";
                public const string HeaderCustomErrEnabled =
"__CustomErrorsEnabled";
                public const string HeaderHTTPReasonPhrase =
"__HttpReasonPhrase";
                public const string HeaderHTTPStatusCode = "__HttpStatusCode";
                public const string HeaderMethodName = "__MethodName";
                public const string HeaderMethodSignature =
"__MethodSignature";
                public const string HeaderOwnMessageContent =
"CompatibleFormatterSyncMessage";
                public const string HeaderTypeName = "__TypeName";
                public const string HeaderURI = "__Uri";
                public const string HeaderUserAgent = "User-Agent";
                public const string OwnMessageAction =
"{D3CD0B54-DA35-461e-BB5E-3CA5369DEAE7}";
                public const string RequestUri = "__RequestUri";
                public const string RequestVerb = "__RequestVerb";
                public const string SOAPAction = "SOAPAction";
                public const string SoapContentType = "text/xml;
charset=\"utf-8\"";
                public const string XMLContent = "text/xml";
        }

        [Serializable]
        public abstract class Message : IMethodCallMessage //, ISerializable
//IMessage
        {
                private readonly Hashtable m_Props;
                [NonSerialized] private LogicalCallContext m_CallContext;
                [NonSerialized] private string m_Uri;

                protected Message()
                {
                        m_Props = new Hashtable();
                        m_Props[Constants.HeaderOwnMessageContent] =
Constants.OwnMessageAction;
                }

                /// <summary>
                /// Конструктор десериализации
                /// </summary>
                /// <param name="info"></param>
                /// <param name="context"></param>
                protected Message(SerializationInfo info, StreamingContext
context) : this()
                {
                        LogicalCallContext = (LogicalCallContext)
info.GetValue(Constants.HeaderCallContext, typeof (LogicalCallContext));
                        Uri = info.GetString(Constants.HeaderURI);
                }

                #region IMethodCallMessage Members

                ///<summary>
                ///Gets an <see cref="T:System.Collections.IDictionary"></see>
that represents a collection of the message's properties.
                ///</summary>
                ///
                ///<returns>
                ///A dictionary that represents a collection of the message's
properties.
                ///</returns>
                ///
                ///<exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public IDictionary Properties
                {
                        get { return m_Props; //m_MessageProperties;
                        }
                }

                /// <summary>
                /// Gets the name of the argument passed to the method.
                /// </summary>
                /// <returns>
                /// The name of the specified argument passed to the method, or
null if the current method is not implemented.
                /// </returns>
                /// <param name="index">The number of the requested argument.
</param>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception>
                public string GetArgName(int index)
                {
                        throw new NotImplementedException();
                }

                /// <summary>
                /// Gets a specific argument as an <see
cref="T:System.Object"></see>.
                /// </summary>
                /// <returns>
                /// The argument passed to the method.
                /// </returns>
                /// <param name="argNum">The number of the requested argument.
</param>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception>
                public object GetArg(int argNum)
                {
                        throw new NotImplementedException();
                }

                /// <summary>
                /// Gets the URI of the specific object that the call is
destined for.
                /// </summary>
                /// <returns>
                /// The URI of the remote object that contains the invoked
method.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public string Uri
                {
                        get { return (string) m_Props[Constants.HeaderURI];
//m_Uri; 
                        }
                        set
                        {
                                //m_Uri = value;
                                m_Props[Constants.HeaderURI] = value;
                        }
                }

                /// <summary>
                /// Gets the name of the invoked method.
                /// </summary>
                /// <returns>
                /// The name of the invoked method.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public string MethodName
                {
                        get { return "GetHashCode"; }
                }

                /// <summary>
                /// Gets the full <see cref="T:System.Type"></see> name of the
specific object that the call is destined for.
                /// </summary>
                /// <returns>
                /// The full <see cref="T:System.Type"></see> name of the
specific object that the call is destined for.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public string TypeName
                {
                        get { return "System.Object"; }
                }

                /// <summary>
                /// Gets an object containing the method signature.
                /// </summary>
                /// <returns>
                /// An object containing the method signature.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public object MethodSignature
                {
                        get { return Type.EmptyTypes; }
                }

                /// <summary>
                /// Gets the number of arguments passed to the method.
                /// </summary>
                /// <returns>
                /// The number of arguments passed to the method.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public int ArgCount
                {
                        get { return 0; }
                }

                /// <summary>
                /// Gets an array of arguments passed to the method.
                /// </summary>
                /// <returns>
                /// An <see cref="T:System.Object"></see> array containing the
arguments passed to the method.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public object[] Args
                {
                        get { return new object[0]; }
                }

                /// <summary>
                /// Gets a value indicating whether the message has variable
arguments.
                /// </summary>
                /// <returns>
                /// true if the method can accept a variable number of
arguments; otherwise, false.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public bool HasVarArgs
                {
                        get { return false; }
                }

                /// <summary>
                /// Gets the <see
cref="T:System.Runtime.Remoting.Messaging.LogicalCallContext"></see> for the
current method call.
                /// </summary>
                /// <returns>
                /// Gets the <see
cref="T:System.Runtime.Remoting.Messaging.LogicalCallContext"></see> for the
current method call.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public LogicalCallContext LogicalCallContext
                {
                        get
                        {
                                //return m_CallContext;
                                return (LogicalCallContext)
m_Props[Constants.HeaderCallContext];
                        }
                        set
                        {
                                m_Props[Constants.HeaderCallContext] = value;
                                //m_CallContext = value;
                        }
                }

                /// <summary>
                /// Gets the <see cref="T:System.Reflection.MethodBase"></see>
of the called method.
                /// </summary>
                /// <returns>
                /// The <see cref="T:System.Reflection.MethodBase"></see> of
the called method.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public MethodBase MethodBase
                {
                        get { return typeof (object).GetMethod("GetHashCode");
}
                }

                /// <summary>
                /// Returns the name of the specified argument that is not
marked as an out parameter.
                /// </summary>
                /// <returns>
                /// The name of a specific argument that is not marked as an
out parameter.
                /// </returns>
                /// <param name="index">The number of the requested in
argument. </param>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception>
                public string GetInArgName(int index)
                {
                        throw new NotImplementedException();
                }

                /// <summary>
                /// Returns the specified argument that is not marked as an out
parameter.
                /// </summary>
                /// <returns>
                /// The requested argument that is not marked as an out
parameter.
                /// </returns>
                /// <param name="argNum">The number of the requested in
argument. </param>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception>
                public object GetInArg(int argNum)
                {
                        throw new NotImplementedException();
                }

                /// <summary>
                /// Gets the number of arguments in the call that are not
marked as out parameters.
                /// </summary>
                /// <returns>
                /// The number of arguments in the call that are not marked as
out parameters.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public int InArgCount
                {
                        get { return 0; }
                }

                /// <summary>
                /// Gets an array of arguments that are not marked as out
parameters.
                /// </summary>
                /// <returns>
                /// An array of arguments that are not marked as out
parameters.
                /// </returns>
                /// <exception cref="T:System.Security.SecurityException">The
immediate caller makes the call through a reference to the interface and does
not have infrastructure permission. </exception><PermissionSet><IPermission
class="System.Security.Permissions.SecurityPermission, mscorlib,
Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1" Flags="Infrastructure" /></PermissionSet>
                public object[] InArgs
                {
                        get { return new object[0]; }
                }

                #endregion

                /// <summary>
                /// Populates a <see
cref="T:System.Runtime.Serialization.SerializationInfo"></see> with the data
needed to serialize the target object.
                /// </summary>
                /// <param name="context">The destination (see <see
cref="T:System.Runtime.Serialization.StreamingContext"></see>) for this
serialization. </param>
                /// <param name="info">The <see
cref="T:System.Runtime.Serialization.SerializationInfo"></see> to populate with
data. </param>
                /// <exception cref="T:System.Security.SecurityException">The
caller does not have the required permission. </exception>
                public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
                {
                        info.AddValue(Constants.HeaderCallContext,
LogicalCallContext);
                        info.AddValue(Constants.HeaderURI, Uri);
                }
        }

        /// <summary>
        /// Запрос на получение сборки с
суррогатами
        /// </summary>
        [Serializable]
        public class SurrogateRequestMessage : Message
        {
                ///<summary>
                ///</summary>
                ///<param name="info"></param>
                ///<param name="context"></param>
                public SurrogateRequestMessage(SerializationInfo info,
StreamingContext context) : base(info, context) 
                {
                }

                ///<summary>
                ///</summary>
                public SurrogateRequestMessage()
                {}
        }

        internal class Program
        {
                private static void Main(string[] args)
                {
                        try
                        {
                                SurrogateRequestMessage sm = new
SurrogateRequestMessage();
                                SoapFormatter formatter = new SoapFormatter();
                                formatter.Context = new
StreamingContext(StreamingContextStates.Other);
                                formatter.AssemblyFormat =
FormatterAssemblyStyle.Full;

                                Type typeMsg = typeof
(SurrogateRequestMessage);
                               
SoapServices.RegisterInteropXmlType(typeMsg.FullName,
typeMsg.Assembly.FullName, typeMsg);
                                MemoryStream ms = new MemoryStream();
                                Header[] headers = new[]
                                                        {
                                                                new
Header(Constants.HeaderOwnMessageContent, Constants.OwnMessageAction)
                                                        };
                                formatter.Serialize(ms, sm, headers);
                                ms.Position = 0;

                                Console.WriteLine("request:");
                               
Console.WriteLine(System.Text.Encoding.UTF8.GetString(ms.GetBuffer()));
                                object o = formatter.Deserialize(ms);
                                Console.WriteLine("Object is {0}",
o.GetType());
                        }
                        catch (Exception e)
                        {
                                Console.WriteLine("Error is {0}", e);
                        }
                        Console.ReadLine();
                }
        }
}

Under MS.NET outputs: 
Object is SoapFormatterTest.SurrogateRequestMessage
Under Mono (svn build) outputs: 
Object is System.String


-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the mono-bugs mailing list