Example #1
0
        /// <summary>
        /// Adds session variables aliases to global variables.
        /// </summary>
        public void RegisterSessionGlobals()
        {
            PhpArray globals, session;

            // do not create session variables table if not exists:
            if ((session = PhpReference.AsPhpArray(AutoGlobals.Session)) == null)
            {
                return;
            }

            // creates globals array if it doesn't exists:
            globals = GlobalVariables;

            // iterates using unbreakable enumerator:
            foreach (KeyValuePair <IntStringKey, object> entry in session)
            {
                PhpReference php_ref = entry.Value as PhpReference;

                // converts the session variable to a reference if it is not one ("no duplicate pointers" rule preserved):
                if (php_ref == null)
                {
                    session[entry.Key] = php_ref = new PhpReference(entry.Value);
                }

                // adds alias to the globals:
                globals[entry.Key] = php_ref;
            }
        }
Example #2
0
        /// <summary>
        /// Applies the new item access on a given variable (<B>ReadRef</B> semantics) that has already been ensured to
        /// be <see cref="PhpArray"/>.
        /// </summary>
        public override PhpReference GetEnsuredRef(object var, ScriptContext context, DTypeDesc caller)
        {
            PhpReference reference = new PhpReference();

            ((PhpArray)var).Add(reference);
            return(reference);
        }
Example #3
0
        /// <summary>
        /// Applies the new item access on a given variable (<B>ReadRef</B> semantics).
        /// </summary>
        public override PhpReference GetRef(ref object var, ScriptContext context, DTypeDesc caller)
        {
            PhpReference reference = new PhpReference();

            Operators.SetItem(reference, ref var);
            return(reference);
        }
Example #4
0
        /// <summary>
        /// Eliminates non-aliased <see cref="PhpReference"/>s. <seealso cref="WrapPropertyValue"/>
        /// </summary>
        /// <param name="val">The object to unwrap.</param>
        /// <returns><paramref name="val"/>'s value if it is a non-aliased <see cref="PhpReference"/>, or
        /// <paramref name="val"/> itself otherwise.</returns>
        internal static object UnwrapPropertyValue(object val)
        {
            PhpReference reference = val as PhpReference;

            if (reference != null && !reference.IsAliased)
            {
                return(reference.Value);
            }
            return(val);
        }
Example #5
0
 public static void SetValue(ref PhpReference variable, object value)
 {
     if (variable == null)
     {
         variable = new PhpReference(value);
     }
     else
     {
         variable.Value = value;
     }
 }
Example #6
0
        /// <summary>
        /// Ends session, i.e. stores content of the $_SESSION array to the <c>HttpContext.Session</c> collection.
        /// </summary>
        /// <param name="abandon">Whether to abandon the session without persisting variables.</param>
        /// <exception cref="SessionException">Session state not available.</exception>
        public void EndSession(bool abandon)
        {
            // checks and changes session state:
            if (disposed || sessionState != SessionStates.Started)
            {
                return;
            }
            sessionState = SessionStates.Closing;

            if (httpContext.Session == null)
            {
                throw new SessionException(CoreResources.GetString("session_state_unavailable"));
            }

            GlobalConfiguration global = Configuration.Global;

            PhpArray variables = PhpReference.AsPhpArray(scriptContext.AutoGlobals.Session);

            if (variables == null)
            {
                variables = new PhpArray();
            }

            try
            {
                if (!abandon)
                {
                    scriptContext.Config.Session.Handler.Persist(variables, scriptContext, httpContext);
                }
                else
                {
                    scriptContext.Config.Session.Handler.Abandoning(scriptContext, httpContext);
                }
            }
            finally
            {
                if (!abandon)
                {
                    // if ASP.NET session state is empty then adds a dump item to preserve the session:
                    if (httpContext.Session.Count == 0)
                    {
                        httpContext.Session.Add(AspNetSessionHandler.PhpNetSessionVars, AspNetSessionHandler.DummySessionItem);
                    }
                }
                else
                {
                    // abandons ASP.NET session:
                    httpContext.Session.Abandon();
                }

                sessionState = SessionStates.Closed;
            }
        }
Example #7
0
 /// <summary>
 /// Adds variables from one auto-global array to another.
 /// </summary>
 /// <param name="dst">A PHP reference to the target array.</param>
 /// <param name="src">A PHP reference to the source array.</param>
 /// <remarks>
 /// Variable values are deeply copied.
 /// If either reference is a <B>null</B> reference or doesn't contain an array, no copying takes place.
 /// </remarks>
 internal static void AddVariables(PhpReference /*!*/ dst, PhpReference /*!*/ src)
 {
     if (dst != null && src != null)
     {
         PhpArray adst = dst.Value as PhpArray;
         PhpArray asrc = src.Value as PhpArray;
         if (adst != null && asrc != null)
         {
             AddVariables(adst, asrc);
         }
     }
 }
Example #8
0
        /// <summary>
        /// Evaluates this chain as if it had the <see cref="PHP.Core.AST.AccessType.ReadRef"/> access type.
        /// </summary>
        /// <param name="context">Current script context.</param>
        /// <returns>The result of chain evaluation.</returns>
        public PhpReference GetReference(ScriptContext context)
        {
            PhpReference reference;

            RuntimeChainElement element = Chain;

            if (element == null)
            {
                // if we are just wrapping the variable with a PhpReference, make a copy
                reference = Variable as PhpReference;
                if (reference == null)
                {
                    reference = new PhpReference(PhpVariable.Copy(Variable, CopyReason.Unknown));
                }

                return(reference);
            }

            // make sure that we have a PhpReference
            reference = PhpVariable.MakeReference(Variable);

            if (element == lastElement)
            {
                // GetPropertyRef/GetItemRef
                return(element.GetRef(ref reference.value, context, Caller));
            }

            // EnsureVariableIsObject/EnsureVariableIsArray
            object var = element.EnsureVariable(ref reference.value, context, Caller);

            if (var == null)
            {
                return(new PhpReference());
            }

            while (element.Next != null)
            {
                // Ensure{Field,Item}Is{Object,Array}
                var = element.Ensure(var, context, Caller);
                if (var == null)
                {
                    return(new PhpReference());
                }

                element = element.Next;
            }

            // GetObjectPropertyRef/GetArrayItemRef
            return(element.GetEnsuredRef(var, context, Caller));
        }
        public static T Call <T>(this ScriptContext context, string /*!*/ functionName, NamingContext namingContext,
                                 Dictionary <string, object> callerLocalVariables, params object[] arguments)
            where T : class
        {
            PhpReference rf = context.Call(functionName, namingContext, callerLocalVariables, arguments);

            if (rf.Value == null)
            {
                return(null);
            }
            else
            {
                return(DuckTyping.Instance.ImplementDuckType <T>(rf.Value));
            }
        }
Example #10
0
        /// <summary>
        /// Starts session if not already started. Loads session variables from <c>HttpContext.Session</c>.
        /// </summary>
        /// <para>
        /// Session state (<c>HttpContext.Session</c>) has to be available at the time of the call.
        /// Otherwise, an exception occurs.
        /// </para>
        /// <para>
        /// Starting the session inheres in importing session variables from the session data store.
        /// The store is specific to the current PHP session handler
        /// defined by configuration option <see cref="LocalConfiguration.SessionSection.Handler"/>.
        /// In the case the ASP.NET handler is active, values from <c>HttpContext.Session</c> are imported to
        /// <c>$_SESSION</c> PHP auto-global variable. Hence, items added to the <c>HttpContext.Session</c> by
        /// non-PHP code after the start of the session will not be visible to PHP code. The <c>$_SESSION</c> variable
        /// has to be updated directly (see <c>ScriptContext.AutoGlobals</c>) to make these items visible to PHP.
        /// </para>
        /// <exception cref="SessionException">Session state not available.</exception>
        public void StartSession()
        {
            // checks and changes session state:
            if (disposed || sessionState != SessionStates.Closed)
            {
                return;
            }
            sessionState = SessionStates.Starting;

            if (httpContext.Session == null)
            {
                throw new SessionException(CoreResources.GetString("session_state_unavailable"));
            }

            EnsureSessionId();

            GlobalConfiguration global    = Configuration.Global;
            PhpArray            variables = null;

            // removes dummy item keeping the session alive:
            if (httpContext.Session[AspNetSessionHandler.PhpNetSessionVars] as string == AspNetSessionHandler.DummySessionItem)
            {
                httpContext.Session.Remove(AspNetSessionHandler.PhpNetSessionVars);
            }

            // loads an array of session variables using the current session handler:
            variables = scriptContext.Config.Session.Handler.Load(scriptContext, httpContext);

            // variables cannot be null:
            if (variables == null)
            {
                variables = new PhpArray();
            }

            // sets the auto-global variable (the previous content of $_SESSION array is discarded):
            PhpReference.SetValue(ref scriptContext.AutoGlobals.Session, variables);

            // copies session variables to $GLOBALS array if necessary:
            if (global.GlobalVariables.RegisterGlobals)
            {
                scriptContext.RegisterSessionGlobals();
            }

            // adds a SID constant:
            UpdateSID();

            sessionState = SessionStates.Started;
        }
Example #11
0
        /// <summary>
        /// Returns names and properties of all instance properties or only PHP fields (including runtime fields).
        /// </summary>
        /// <param name="instance">The instance being serialized.</param>
        /// <param name="phpFieldsOnly"><B>True</B> to return only PHP fields, <B>false</B> to return all
        /// instance properties.</param>
        /// <returns>Name-value pairs. Names are properly formatted for serialization.</returns>
        public static IEnumerable <KeyValuePair <string, object> > EnumerateSerializableProperties(
            DObject /*!*/ instance,
            bool phpFieldsOnly)
        {
            // enumerate CT properties:
            foreach (KeyValuePair <VariableName, DPropertyDesc> pair in instance.TypeDesc.EnumerateProperties())
            {
                // skip static props
                if (pair.Value.IsStatic)
                {
                    continue;
                }

                // skip CLR fields and props if asked so
                if (phpFieldsOnly && !(pair.Value is DPhpFieldDesc))
                {
                    continue;
                }

                object       property_value     = pair.Value.Get(instance);
                PhpReference property_value_ref = property_value as PhpReference;

                if (property_value_ref == null || property_value_ref.IsSet)
                {
                    yield return(new KeyValuePair <string, object>(
                                     Serialization.FormatPropertyName(pair.Value, pair.Key.ToString()),
                                     property_value));
                }
            }

            // enumerate RT fields:
            if (instance.RuntimeFields != null)
            {
                foreach (var pair in instance.RuntimeFields)
                {
                    yield return(new KeyValuePair <string, object>(pair.Key.String, pair.Value));
                }
            }
        }
Example #12
0
        public PhpReference PeekReferenceUnchecked(int i)
        {
            object          item = Items[Top - i];
            PhpReference    result;
            PhpRuntimeChain php_chain;

            // the caller may not pushed a reference although the formal argument is a reference:
            // it doesn't matter if called by callback:
            if ((result = item as PhpReference) == null)
            {
                // caller may have pushed a runtime chain => evaluate it:
                if ((php_chain = item as PhpRuntimeChain) != null)
                {
                    // call state has to be stored since chain can call arbitrary user code:
                    CallState call_state = SaveCallState();
                    result = php_chain.GetReference(Context);
                    RestoreCallState(call_state);
                }
                else
                {
                    // the reason of copy is not exactly known (it may be returning by copy as well as passing by copy):
                    result = new PhpReference(PhpVariable.Copy(item, CopyReason.Unknown));

                    // Reports an error in the case that we are not called by callback.
                    // Although, this error is fatal one can switch throwing exceptions off.
                    // If this is the case the afterwards behavior will be the same as if callback was called.
                    if (!Callback)
                    {
                        // warning (can invoke user code => we have to save and restore callstate):
                        CallState call_state = SaveCallState();

                        PhpException.ArgumentNotPassedByRef(i, CalleeName);
                        RestoreCallState(call_state);
                    }
                }
            }
            return(result);
        }
Example #13
0
        public PhpReference PeekReference(int i)
        {
            PhpReference result;

            if (ArgCount >= i)
            {
                // peeks the reference:
                result = PeekReferenceUnchecked(i);

                // stores the value back to the stack so that user args functions can work with it:
                Items[Top - i] = result;
            }
            else
            {
                result = new PhpReference();

                // warning (can invoke user code => we have to save and restore callstate):
                CallState call_state = SaveCallState();
                PhpException.MissingArgument(i, CalleeName);
                RestoreCallState(call_state);
            }

            return(result);
        }
Example #14
0
        private static void WriteAutoGlobal(TextWriter output, ScriptContext context, string name, PhpReference autoglobal)
        {
            PhpArray array;

            if ((array = autoglobal.Value as PhpArray) != null)
            {
                foreach (KeyValuePair <IntStringKey, object> entry in array)
                {
                    HtmlVarRow(output, name, entry.Key.Object, entry.Value);
                }
            }
        }
Example #15
0
 /// <summary>
 /// Adds a level of indirection to a specified argument.
 /// Supresses checks that disables a reference to containe another reference.
 /// </summary>
 /// <param name="i">An index of argument starting from 1.</param>
 internal void AddIndirection(int i)
 {
     // preserves "no duplicate pointers" invariant:
     Items[Top - i] = new PhpReference(Items[Top - i], true);
 }
Example #16
0
 public static PhpArray AsPhpArray(PhpReference variable)
 {
     return(AsType <PhpArray>(variable));
 }
Example #17
0
 public static T AsType <T>(PhpReference variable) where T : class
 {
     return((variable != null) ? variable.Value as T : null);
 }
Example #18
0
 protected override void SetArrayItemRefOverride(object key, PhpReference value)
 {
     ScriptContext.CurrentContext.AbortSetterChain(false);
 }
Example #19
0
 public DebuggerProxy(PhpReference reference)
 {
     _reference = reference;
 }
Example #20
0
 protected override void SetArrayItemRefOverride(object key, PhpReference value)
 {
     PhpException.VariableMisusedAsArray(obj, true);
 }
Example #21
0
        public static void GetObjectData(DObject /*!*/ instance, SerializationInfo /*!*/ info, StreamingContext strctx)
        {
            info.SetType(typeof(Deserializer));

            SerializationContext context = SerializationContext.CreateFromStreamingContext(strctx);

            bool     sleep_called;
            PhpArray sleep_result;

            // try to get the caches __sleep result
            if (context.SleepResults.TryGetValue(instance, out sleep_result))
            {
                if (Object.ReferenceEquals(sleep_result, SerializationContext.NoSleepResultSingleton))
                {
                    sleep_called = false;
                    sleep_result = null;
                }
                else
                {
                    sleep_called = true;
                }
            }
            else
            {
                sleep_result = instance.Sleep(context.ClassContext, context.ScriptContext, out sleep_called);
                context.SleepResults.Add(instance, (sleep_called ? sleep_result : SerializationContext.NoSleepResultSingleton));
            }

            if (sleep_called && sleep_result == null)
            {
                // __sleep did not return an array -> this instance will deserialize as NULL
                info.AddValue(__PHP_Incomplete_Class.ClassNameFieldName, String.Empty);
            }
            else
            {
                // if we have a sleep result, serialize fields according to it, otherwise serialize all fields

                IEnumerable <KeyValuePair <string, object> > serializable_properties;
                object real_object = null;

                if (sleep_result == null)
                {
                    serializable_properties = Serialization.EnumerateSerializableProperties(
                        instance,
                        true);                         // get PHP fields only

                    // serialize CLR real object in the "CLR way"
                    if (!(instance is PhpObject))
                    {
                        real_object = instance.RealObject;
                    }
                }
                else
                {
                    serializable_properties = Serialization.EnumerateSerializableProperties(
                        instance,
                        sleep_result,
                        context.ScriptContext);
                }

                bool type_name_serialized   = false;
                bool real_object_serialized = false;

                foreach (KeyValuePair <string, object> pair in serializable_properties)
                {
                    if (pair.Key == __PHP_Incomplete_Class.ClassNameFieldName)
                    {
                        type_name_serialized = true;
                    }

                    if (pair.Key == ClrRealObjectSerializationInfoKey)
                    {
                        // unwrap the possibly wrapped CLR real object
                        info.AddValue(pair.Key, PhpVariable.Unwrap(pair.Value));

                        real_object_serialized = true;
                    }
                    else
                    {
                        PhpReference reference = pair.Value as PhpReference;
                        info.AddValue(pair.Key, WrapPropertyValue(pair.Value));
                    }
                }

                // if the type name has not been serialized, do it now
                if (!type_name_serialized)
                {
                    info.AddValue(__PHP_Incomplete_Class.ClassNameFieldName, instance.TypeName);
                }

                // if the real object has not been serialized, do it now
                if (!real_object_serialized)
                {
                    info.AddValue(ClrRealObjectSerializationInfoKey, real_object);
                }
            }
        }