Example #1
0
		/// <summary>
		/// Adds items of "array" to "result" merging those whose string keys are the same.
		/// </summary>
		private static bool MergeRecursiveInternal(PhpArray/*!*/ result, PhpArray/*!*/ array, bool deepCopy)
		{
			foreach (KeyValuePair<IntStringKey, object> entry in array)
			{
				if (entry.Key.IsString)
				{
					if (result.ContainsKey(entry.Key))
					{
						// the result array already contains the item => merging take place
						object xv = result[entry.Key];
						object yv = entry.Value;

						// source item:
						object x = PhpVariable.Dereference(xv);
						object y = PhpVariable.Dereference(yv);
						PhpArray ax = x as PhpArray;
						PhpArray ay = y as PhpArray;

						// if x is not a reference then we can reuse the ax array for the result
						// since it has been deeply copied when added to the resulting array:
						PhpArray item_result = (deepCopy && x == xv && ax != null) ? ax : new PhpArray();

						if (ax != null && ay != null)
						{
							if (ax != item_result)
								ax.AddTo(item_result, deepCopy);

							if (ax.Visited && ay.Visited) return false;

							ax.Visited = true;
							ay.Visited = true;

							// merges ay to the item result (may lead to stack overflow, 
							// but only with both arrays recursively referencing themselves - who cares?):
							bool finite = MergeRecursiveInternal(item_result, ay, deepCopy);

							ax.Visited = false;
							ay.Visited = false;

							if (!finite) return false;
						}
						else
						{
							if (ax != null)
							{
								if (ax != item_result)
									ax.AddTo(item_result, deepCopy);
							}
							else
							{
								/*if (x != null)*/
									item_result.Add((deepCopy) ? PhpVariable.DeepCopy(x) : x);
							}

							if (ay != null) ay.AddTo(item_result, deepCopy);
							else /*if (y != null)*/ item_result.Add((deepCopy) ? PhpVariable.DeepCopy(y) : y);
						}

						result[entry.Key] = item_result;
					}
					else
					{
						// PHP does no dereferencing when items are not merged:
						result.Add(entry.Key, (deepCopy) ? PhpVariable.DeepCopy(entry.Value) : entry.Value);
					}
				}
				else
				{
					// PHP does no dereferencing when items are not merged:
					result.Add((deepCopy) ? PhpVariable.DeepCopy(entry.Value) : entry.Value);
				}
			}

			return true;
		}
Example #2
0
		public static bool KeyExists(object key, PhpArray array)
		{
			if (array == null)
			{
				PhpException.ArgumentNull("array");
				return false;
			}

			IntStringKey array_key;
			if (Core.Convert.ObjectToArrayKey(key, out array_key))
				return array.ContainsKey(array_key);
				
			PhpException.Throw(PhpError.Warning, CoreResources.GetString("illegal_offset_type")); 
			return false;
		}
Example #3
0
        public static PhpArray FillKeys(PhpArray keys, object value)
        {
            if (keys == null)
            {
                PhpException.ArgumentNull("keys");
                return null;
            }

            var result = new PhpArray(keys.Count);
            foreach (var x in keys)
            {
                IntStringKey key;
                if (Core.Convert.ObjectToArrayKey(x.Value, out key) &&
                    !result.ContainsKey(key))
                {
                    result.Add(key, value);
                }
            }

            // makes deep copies of all added items:
            result.InplaceCopyOnReturn = true;
            return result;
        }
Example #4
0
        private void UpdateValueAndIndexArrays(ElementRecord elementRecord, ref TextRecord textRecord, PhpArray values, PhpArray indices, bool middle)
        {
            // if we have no valid data in the middle, just end
            if (middle && textRecord == null)
                return;

            if (!middle && elementRecord.State == ElementState.Interior)
                UpdateValueAndIndexArrays(elementRecord, ref textRecord, values, indices, true);
            
            if (values != null)
            {
                PhpArray arrayRecord = new PhpArray();

                arrayRecord.Add("tag", elementRecord.ElementName);
                arrayRecord.Add("level", elementRecord.Level);

                if (elementRecord.State == ElementState.Beginning)
                    arrayRecord.Add("type", middle ? "open" : "complete");
                else
                    arrayRecord.Add("type", middle ? "cdata" : "close");

                if (textRecord != null)
                    arrayRecord.Add("value", textRecord.Text);

                if (elementRecord.State == ElementState.Beginning && elementRecord.Attributes.Count != 0)
                    arrayRecord.Add("attributes", elementRecord.Attributes);

                values.Add(arrayRecord);

                if (indices != null)
                {
                    PhpArray elementIndices;

                    if (!indices.ContainsKey(elementRecord.ElementName))
                    {
                        elementIndices = new PhpArray();
                        indices.Add(elementRecord.ElementName, elementIndices);
                    }
                    else
                        elementIndices = (PhpArray)indices[elementRecord.ElementName];

                    // add the max index (last inserted value)
                    elementIndices.Add(values.MaxIntegerKey);
                }
            }

            textRecord = null;
        }
Example #5
0
        public static PhpArray FillKeys(PhpArray keys, object value)
        {
            PhpArray result = new PhpArray(keys.Count);

            if (keys != null)
                foreach (var x in keys)
                {
                    IntStringKey key;
                    if (!PHP.Core.Convert.ObjectToArrayKey(x.Value, out key))
                        continue;

                    if (!result.ContainsKey(key))
                        result.Add(key, value);
                }

            // makes deep copies of all added items:
            result.InplaceCopyOnReturn = true;
            return result;
        }
		/// <summary>
		/// Loads $_SERVER from HttpRequest.ServerVariables.
		/// </summary>
		private void InitializeServerVariables(LocalConfiguration/*!*/ config, HttpContext context)
		{
            if (context == null)
            {
                Server.Value = new PhpArray();
                return;
            }

            Debug.Assert(config != null);            

			PhpArray array, argv;

            var request = context.Request;
            var serverVariables = request.ServerVariables;

            Server.Value = array = new PhpArray(0, /*serverVariables.Count*/64);

			// adds variables defined by ASP.NET and IIS:
            LoadFromCollection(array, serverVariables);

			// adds argv, argc variables:
			if (Configuration.Global.GlobalVariables.RegisterArgcArgv)
			{
                array["argv"] = argv = new PhpArray(1) { request.QueryString };
                array["argc"] = 0;
			}

			// additional variables defined in PHP manual:
            array["PHP_SELF"] = request.Path;

			try
			{
                array["DOCUMENT_ROOT"] = request.MapPath("/"); // throws exception under mod_aspdotnet
			}
			catch
			{
				array["DOCUMENT_ROOT"] = null;
			}

            array["SERVER_ADDR"] = serverVariables["LOCAL_ADDR"];
            array["REQUEST_URI"] = request.RawUrl;
			array["REQUEST_TIME"] = DateTimeUtils.UtcToUnixTimeStamp(context.Timestamp.ToUniversalTime());
            array["SCRIPT_FILENAME"] = request.PhysicalPath;

			//IPv6 is the default in IIS7, convert to an IPv4 address (store the IPv6 as well)
            if (request.UserHostAddress.Contains(":"))
			{
                array["REMOTE_ADDR_IPV6"] = request.UserHostAddress;

                if (request.UserHostAddress == "::1")
                {
                    array["REMOTE_ADDR"] = array["SERVER_ADDR"] = "127.0.0.1";
                }
                else foreach (IPAddress IPA in Dns.GetHostAddresses(request.UserHostAddress))
                    {
                        if (IPA.AddressFamily.ToString() == "InterNetwork")
                        {
                            array["REMOTE_ADDR"] = IPA.ToString();
                            break;
                        }
                    }
			}

            // PATH_INFO
            // should contain partial path information only
            // note: IIS has AllowPathInfoForScriptMappings property that do the thing ... but ISAPI does not work then
            // hence it must be done here manually

            if (array.ContainsKey("PATH_INFO"))
            {
                string path_info = (string)array["PATH_INFO"];
                string script_name = (string)array["SCRIPT_NAME"];
                    
                // 'ORIG_PATH_INFO'
                // Original version of 'PATH_INFO' before processed by PHP. 
                array["ORIG_PATH_INFO"] = path_info;
                    
                // 'PHP_INFO'
                // Contains any client-provided pathname information trailing the actual script filename
                // but preceding the query string, if available. For instance, if the current script was
                // accessed via the URL http://www.example.com/php/path_info.php/some/stuff?foo=bar,
                // then $_SERVER['PATH_INFO'] would contain /some/stuff. 
                    
                // php-5.3.2\sapi\isapi\php5isapi.c:
                // 
                // strncpy(path_info_buf, static_variable_buf + scriptname_len - 1, sizeof(path_info_buf) - 1);    // PATH_INFO = PATH_INFO.SubString(SCRIPT_NAME.Length);


                array["PATH_INFO"] = (script_name.Length <= path_info.Length) ? path_info.Substring(script_name.Length) : string.Empty;
            }
		}
Example #7
0
 private object BindArray(PhpArray array, Type targetType)
 {
     if (targetType.IsArray)
     {
         array = (PhpArray) (array.ContainsKey("item") ? array["item"] : array); // TODO: ???
         return BindArrayToArray(array, targetType);
     }
     else
         return BindArrayToObject(array, targetType);
 }