예제 #1
0
파일: PhpZlib.cs 프로젝트: jiahao42/weverca
        public static PhpBytes GzCompress(PhpBytes data, int level)
        {
            if ((level < -1) || (level > 9))
            {
                PhpException.Throw(PhpError.Warning, String.Format("compression level ({0}) must be within -1..9", level));
                return(null);
            }

            int length_bound = data.Length + (data.Length / PHP_ZLIB_MODIFIER) + 15 + 1;

            byte[] output;

            try
            {
                output = new byte[length_bound];
            }
            catch (OutOfMemoryException)
            {
                return(null);
            }

            int status;

            status = ZlibCompress(ref output, data.ReadonlyData, level);

            if (status == zlibConst.Z_OK)
            {
                return(new PhpBytes(output));
            }
            else
            {
                PhpException.Throw(PhpError.Warning, zError(status));
                return(null);
            }
        }
예제 #2
0
        private static Value _md5(FlowController flow, Value[] arguments)
        {
            stringConverter.SetContext(flow);
            var stringValue = stringConverter.EvaluateToString(arguments[0]);

            if (stringValue == null)
            {
                return(flow.OutSet.AnyStringValue);
            }

            var phpBytes = new PhpBytes(stringValue.Value);

            Debug.Assert(arguments.Length > 0);

            if (arguments.Length > 1)
            {
                booleanConverter.SetContext(flow.OutSet.Snapshot);
                var isRawOutput = booleanConverter.EvaluateToBoolean(arguments[1]);

                if ((isRawOutput == null) || isRawOutput.Value)
                {
                    // TODO: Implement precisely
                    return(flow.OutSet.AnyStringValue);
                }
            }

            return(flow.OutSet.CreateString(PhpHash.MD5(phpBytes)));
        }
예제 #3
0
        /// <summary>
        /// Deserializes a graph of connected object from a byte array using a given formatter.
        /// </summary>
        /// <param name="bytes">The byte array to deserialize the graph from.</param>
        /// <param name="caller">DTypeDesc of the caller's class context if it is known or UnknownTypeDesc if it should be determined lazily.</param>
        /// <returns>
        /// The deserialized object graph or an instance of <see cref="PhpReference"/> containing <B>false</B> on error.
        /// </returns>
        /// <exception cref="PhpException">Deserialization failed (Notice).</exception>
        public PhpReference Deserialize(PhpBytes bytes, DTypeDesc caller)
        {
            MemoryStream stream = new MemoryStream(bytes.ReadonlyData);
            object       result = null;

            try
            {
                try
                {
                    // deserialize the data
                    result = GetFormatter(caller).Deserialize(stream);
                }
                catch (System.Reflection.TargetInvocationException e)
                {
                    throw e.InnerException;
                }
            }
            catch (SerializationException e)
            {
                PhpException.Throw(PhpError.Notice, LibResources.GetString("deserialization_failed",
                                                                           e.Message, stream.Position, stream.Length));
                return(new PhpReference(false));
            }

            return(PhpVariable.MakeReference(result));
        }
예제 #4
0
파일: Web.cs 프로젝트: ikvm/Phalanger
 public static string EncodeBase64(PhpBytes data_to_encode)
 {
     if (data_to_encode == null)
     {
         return(null);
     }
     return(System.Convert.ToBase64String(data_to_encode.ReadonlyData));
 }
예제 #5
0
파일: PhpJson.cs 프로젝트: jiahao42/weverca
        public static PhpReference Unserialize(PhpBytes json)
        {
            if (json == null)
            {
                return(null);
            }

            return(PhpJsonSerializer.Default.Deserialize(json, UnknownTypeDesc.Singleton));
        }
예제 #6
0
        public static string Encode(PhpBytes bytes)
        {
            byte[]        data   = (bytes != null) ? bytes.ReadonlyData : ArrayUtils.EmptyBytes;
            StringBuilder result = new StringBuilder((int)(data.Length * 1.38 + data.Length + 1));

            Encode(data, new StringWriter(result));

            return(result.ToString());
        }
예제 #7
0
        private void AddFormData(object data)
        {
            //currentData.Type = FormType.FORM_CONTENT;

            PhpBytes bytes = PhpVariable.AsBytes(data);

            currentData.Data = bytes.ReadonlyData;

            NextDataIsFooter();
        }
예제 #8
0
        static void Concat()
        {
            PhpBytes a = new PhpBytes(new byte[] { 61, 62, 63 });
            string   b = "-hello-";
            PhpBytes c = new PhpBytes(new byte[] { 61, 61, 61 });
            string   d = "-bye-";

            object result = Operators.Concat(a, b, c, d);

            Assert.IsTrue(Operators.StrictEquality(result, "=>?-hello-===-bye-"));
        }
예제 #9
0
        public static PhpReference Unserialize(PHP.Core.Reflection.DTypeDesc caller, PhpBytes bytes)
        {
            if (bytes == null || bytes.Length == 0)
            {
                return(new PhpReference(false));
            }

            LibraryConfiguration config = LibraryConfiguration.GetLocal(ScriptContext.CurrentContext);

            return(config.Serialization.DefaultSerializer.Deserialize(bytes, caller));
        }
예제 #10
0
        private static string StrrChr(object haystack, object needle, bool beforeNeedle /*=false*/, getEncoding encodingGetter, bool ignoreCase)
        {
            string uhaystack = ObjectToString(haystack, encodingGetter);
            char   cneedle;
            {
                string uneedle;

                if (needle is string)
                {
                    uneedle = (string)needle;
                }
                else if (needle is PhpString)
                {
                    uneedle = ((IPhpConvertible)needle).ToString();
                }
                else if (needle is PhpBytes)
                {
                    Encoding encoding = encodingGetter();
                    if (encoding == null)
                    {
                        return(null);
                    }

                    PhpBytes bytes = (PhpBytes)needle;
                    uneedle = encoding.GetString(bytes.ReadonlyData, 0, bytes.Length);
                }
                else
                {   // needle as a character number
                    Encoding encoding = encodingGetter();
                    if (encoding == null)
                    {
                        return(null);
                    }

                    uneedle = encoding.GetString(new byte[] { unchecked ((byte)Core.Convert.ObjectToInteger(needle)) }, 0, 1);
                }

                if (string.IsNullOrEmpty(uneedle))
                {
                    return(null);
                }

                cneedle = uneedle[0];
            }

            int index = (ignoreCase) ? uhaystack.ToLower().LastIndexOf(char.ToLower(cneedle)) : uhaystack.LastIndexOf(cneedle);

            if (index < 0)
            {
                return(null);
            }

            return((beforeNeedle) ? uhaystack.Remove(index) : uhaystack.Substring(index));
        }
예제 #11
0
파일: PhpZlib.cs 프로젝트: jiahao42/weverca
        public static PhpBytes GzDeflate(PhpBytes data, int level)
        {
            if ((level < -1) || (level > 9))
            {
                PhpException.Throw(PhpError.Warning, String.Format("compression level ({0}) must be within -1..9", level));
                return(null);
            }

            ZStream zs = new ZStream();

            zs.next_in  = data.ReadonlyData;
            zs.avail_in = data.Length;

            // heuristic for max data length
            zs.avail_out = data.Length + data.Length / PHP_ZLIB_MODIFIER + 15 + 1;
            zs.next_out  = new byte[zs.avail_out];

            // -15 omits the header (undocumented feature of zlib)
            int status = zs.deflateInit(level, -MAX_WBITS);

            if (status == zlibConst.Z_OK)
            {
                status = zs.deflate(zlibConst.Z_FINISH);
                if (status != zlibConst.Z_STREAM_END)
                {
                    zs.deflateEnd();
                    if (status == zlibConst.Z_OK)
                    {
                        status = zlibConst.Z_BUF_ERROR;
                    }
                }
                else
                {
                    status = zs.deflateEnd();
                }
            }

            if (status == zlibConst.Z_OK)
            {
                byte[] result = new byte[zs.total_out];
                Buffer.BlockCopy(zs.next_out, 0, result, 0, (int)zs.total_out);
                return(new PhpBytes(result));
            }
            else
            {
                PhpException.Throw(PhpError.Warning, zError(status));
                return(null);
            }
        }
예제 #12
0
        public override object Filter(object input, bool closing)
        {
            PhpBytes bInput = Core.Convert.ObjectToPhpBytes(input);

            if (bInput != null)
            {
                int offset = 0;
                return(new PhpBytes(FilterInner(bInput.ReadonlyData, ref offset, closing)));
            }
            else
            {
                Debug.Fail("InflateFilter expects chunks to be convertible to PhpBytes.");
                return(null);
            }
        }
예제 #13
0
            public override object GetValue(Literal node)
            {
                var value = node.ValueObj;

                if (value != null)
                {
                    // wrap CLR value to PHP value type
                    if (value.GetType() == typeof(byte[]))
                    {
                        value = new PhpBytes((byte[])value);
                    }
                }

                Debug.Assert(PhpVariable.HasLiteralPrimitiveType(value));

                return(value);
            }
예제 #14
0
파일: PhpJson.cs 프로젝트: jiahao42/weverca
        public static PhpReference Unserialize(PhpBytes json, bool assoc /* = false*/, int depth /* = 512*/, JsonDecodeOptions options /* = 0 */)
        {
            if (json == null)
            {
                return(null);
            }

            return(new PhpJsonSerializer(
                       new JsonFormatter.EncodeOptions(),
                       new JsonFormatter.DecodeOptions()
            {
                Assoc = assoc,
                Depth = depth,
                BigIntAsString = (options & JsonDecodeOptions.JSON_BIGINT_AS_STRING) != 0
            }
                       ).Deserialize(json, UnknownTypeDesc.Singleton));
        }
예제 #15
0
        /// <summary>
        /// Converts PhpBytes using specified encoding. If any other object is provided, encoding is not performed.
        /// </summary>
        /// <param name="str"></param>
        /// <param name="encodingGetter"></param>
        /// <returns></returns>
        private static string ObjectToString(object str, getEncoding encodingGetter)
        {
            if (str is PhpBytes)
            {
                PhpBytes bytes    = (PhpBytes)str;
                Encoding encoding = encodingGetter();
                if (encoding == null)
                {
                    return(null);
                }

                return(encoding.GetString(bytes.ReadonlyData, 0, bytes.Length));
            }
            else
            {
                // .NET String should be always UTF-16, given encoding is irrelevant
                return(PHP.Core.Convert.ObjectToString(str));
            }
        }
예제 #16
0
파일: PhpZlib.cs 프로젝트: jiahao42/weverca
        public static PhpBytes GzUncompress(PhpBytes data, int length)
        {
            if (length < 0)
            {
                PhpException.Throw(PhpError.Warning, String.Format("length {0} must be greater or equal zero", length));
                return(null);
            }

            int ilength;

            int factor = 1, maxfactor = 16;

            byte[] output;
            int    status;

            do
            {
                ilength = length != 0 ? length : (data.Length * (1 << factor++));

                try
                {
                    output = new byte[ilength];
                }
                catch (OutOfMemoryException)
                {
                    return(null);
                }

                status = ZlibUncompress(ref output, data.ReadonlyData);
            }while ((status == zlibConst.Z_BUF_ERROR) && (length == 0) && (factor < maxfactor));

            if (status == zlibConst.Z_OK)
            {
                return(new PhpBytes(output));
            }
            else
            {
                PhpException.Throw(PhpError.Warning, zError(status));
                return(null);
            }
        }
예제 #17
0
            private void Callback(IAsyncResult ar)
            {
                if (access == StreamAccessOptions.Read)
                {
                    int count = stream.EndRead(ar);
                    if (count > 0)
                    {
                        if (count != buffer.Length)
                        {
                            // TODO: improve streams
                            var buf = new byte[count];
                            Buffer.BlockCopy(buffer.ReadonlyData, 0, buf, 0, count);
                            phpStream.WriteBytes(new PhpBytes(buf));
                        }
                        else
                        {
                            phpStream.WriteBytes(buffer);
                        }

                        stream.BeginRead(buffer.Data, 0, buffer.Length, callback, ar.AsyncState);
                    }
                    else
                    {
                        stream.Close();
                    }
                }
                else
                {
                    buffer = phpStream.ReadBytes(BufferSize);
                    if (buffer != null)
                    {
                        stream.BeginWrite(buffer.ReadonlyData, 0, buffer.Length, callback, ar.AsyncState);
                    }
                    else
                    {
                        stream.EndWrite(ar);
                        stream.Close();
                    }
                }
            }
예제 #18
0
        public static string GuidToString(PhpBytes binary, bool shortFormat)
        {
            if (binary == null || binary.Length == 0)
            {
                return(String.Empty);
            }

            if (binary.Length != 16)
            {
                PhpException.InvalidArgument("binary", LibResources.GetString("arg:invalid_length"));
                return(null);
            }

            if (shortFormat)
            {
                return(new Guid(binary.ReadonlyData).ToString("D").ToUpper());
            }
            else
            {
                return(PHP.Core.StringUtils.BinToHex(binary.ReadonlyData, null).ToUpper());
            }
        }
예제 #19
0
        /// <summary>
        /// Compress given data using compressor named in contentEncoding. Set the response header accordingly.
        /// </summary>
        /// <param name="data">PhpBytes or string to be compressed.</param>
        /// <param name="httpcontext">Current HttpContext.</param>
        /// <param name="contentEncoding">gzip or deflate</param>
        /// <returns>Byte stream of compressed data.</returns>
        private static PhpBytes DoGzipHandler(object data, HttpContext /*!*/ httpcontext, ContentEncoding contentEncoding)
        {
            PhpBytes phpbytes = data as PhpBytes;

            var inputbytes = (phpbytes != null) ?
                             phpbytes.ReadonlyData :
                             Configuration.Application.Globalization.PageEncoding.GetBytes(PHP.Core.Convert.ObjectToString(data));

            using (var outputStream = new System.IO.MemoryStream())
            {
                System.IO.Stream compressionStream;
                switch (contentEncoding)
                {
                case ContentEncoding.gzip:
                    compressionStream = new System.IO.Compression.GZipStream(outputStream, System.IO.Compression.CompressionMode.Compress);
                    break;

                case ContentEncoding.deflate:
                    compressionStream = new System.IO.Compression.DeflateStream(outputStream, System.IO.Compression.CompressionMode.Compress);
                    break;

                default:
                    throw new ArgumentException("Not recognized content encoding to be compressed to.", "contentEncoding");
                }

                using (compressionStream)
                {
                    compressionStream.Write(inputbytes, 0, inputbytes.Length);
                }

                //Debug.Assert(
                //    ScriptContext.CurrentContext.Headers["content-encoding"] != contentEncoding,
                //    "The content encoding was already set to '" + contentEncoding + "'. The ob_gzhandler() was called subsequently probably.");

                ScriptContext.CurrentContext.Headers["content-encoding"] = contentEncoding.ToString();

                return(new PhpBytes(outputStream.ToArray()));
            }
        }
예제 #20
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <remarks>TODO: move to CodeGenerator.</remarks>
		internal void EmitLoadPhpBytes(PhpBytes/*!*/ value)
		{
            Debug.Assert(value != null);

            // create array of bytes
            LdcI4(value.Length);
            Emit(OpCodes.Newarr, typeof(byte));

            if (value.Length > 0)   // not valid for zero-length byte arrays
            {
                FieldBuilder datafld = this.DefineInitializedData(
                        string.Concat("byte'", value.ReadonlyData.Length.ToString("x"), "'", value.ReadonlyData.GetHashCode().ToString()),
                        value.ReadonlyData,
                        FieldAttributes.Assembly | FieldAttributes.Static);

                Emit(OpCodes.Dup);
                Emit(OpCodes.Ldtoken, datafld);
                Emit(OpCodes.Call, Methods.InitializeArray);
            }

			Emit(OpCodes.Newobj, Constructors.PhpBytes_ByteArray);
		}
예제 #21
0
파일: PhpZlib.cs 프로젝트: jiahao42/weverca
 public static int GzWrite(PhpResource zp, PhpBytes str)
 {
     return(GzWrite(zp, str, -1));
 }
예제 #22
0
파일: PhpZlib.cs 프로젝트: jiahao42/weverca
 public static int GzPutString(PhpResource zp, PhpBytes str, int length)
 {
     return(GzWrite(zp, str, length));
 }
예제 #23
0
파일: PhpJson.cs 프로젝트: jiahao42/weverca
 public static PhpReference Unserialize(PhpBytes json, bool assoc /* = false*/, int depth /* = 512*/)
 {
     return(Unserialize(json, assoc, depth, JsonDecodeOptions.Default));
 }
예제 #24
0
파일: PhpZlib.cs 프로젝트: jiahao42/weverca
 public static int GzWrite(PhpResource zp, PhpBytes str, int length)
 {
     return(PhpFile.Write(zp, str, length));
 }
예제 #25
0
 /// <summary>
 /// Initializes a new instance of the StringLiteral class.
 /// </summary>
 public BinaryStringLiteral(Position position, PhpBytes /*!*/ value)
     : base(position)
 {
     this.value = value;
 }
예제 #26
0
        public static PhpBytes exif_thumbnail(string filename, PhpReference width, PhpReference height, PhpReference imagetype)
        {
            if (string.IsNullOrEmpty(filename))
            {
                PhpException.Throw(PhpError.Warning, Utils.Resources.GetString("filename_cannot_be_empty"));
                return(null);
            }

            if (imagetype != null)
            {
                PhpException.ArgumentValueNotSupported("imagetype", "!=null");
            }

            Bitmap thumbnail = null;

            PhpBytes bytes, result;

            bytes = Utils.ReadPhpBytes(filename);

            if (bytes == null)
            {
                return(null);
            }

            // get thumbnail from <filename>'s content:
            using (MemoryStream ms = new MemoryStream(bytes.ReadonlyData))
            {
                try
                {
                    using (Bitmap image = (Bitmap)Image.FromStream(ms))
                    {
                        thumbnail = (Bitmap)image.GetThumbnailImage(0, 0, () => true, IntPtr.Zero);
                    }
                }
                catch
                {
                    return(null);
                }
            }

            if (thumbnail == null)
            {
                return(null);
            }

            //
            if (width != null)
            {
                width.Value = thumbnail.Width;
            }

            if (height != null)
            {
                height.Value = thumbnail.Height;
            }

            using (MemoryStream ms2 = new MemoryStream())
            {
                thumbnail.Save(ms2, ImageFormat.Png);
                result = new PhpBytes(ms2.GetBuffer());
            }

            thumbnail.Dispose();

            return(result);
        }
예제 #27
0
        public void UploadData(object data)
        {
            PhpBytes bytes = PhpVariable.AsBytes(data);

            UploadData(bytes.ReadonlyData);
        }
예제 #28
0
 /// <summary>
 /// Called only by Analyzer. On this instance Analyze method will not be called.
 /// </summary>
 internal BinaryStringLiteral(Position position, PhpBytes value, AccessType access)
     : base(position)
 {
     this.value  = value;
     this.access = access;
 }
예제 #29
0
        public override object Filter(object input, bool closing)
        {
            // TODO: not the most efficient method - after the filters are upgraded to bucket lists, update this

            PhpBytes bInput = Core.Convert.ObjectToPhpBytes(input);

            if (bInput != null)
            {
                if (_state == UncompressionState.Failed)
                {
                    // failed filter should not get any more calls
                    PhpException.Throw(PhpError.Warning, "using filter in failed state");
                    return(null);
                }

                if (_state == UncompressionState.PostTrailer)
                {
                    // post trailer - ignore everything
                    if (closing)
                    {
                        _state = UncompressionState.Finished;
                    }

                    return(new PhpBytes());
                }

                if (_state == UncompressionState.Finished)
                {
                    // finished filter should not get any more data
                    PhpException.Throw(PhpError.Warning, "using filter in finished state");
                    return(null);
                }

                if (_state == UncompressionState.Passthrough)
                {
                    // this is not gzip data format - pass the data through
                    return(new PhpBytes(bInput));
                }

                // enqueue the block
                _chunkQueue.EnqueueByteBlock(bInput.ReadonlyData, 0, bInput.Length);

                if (_state == UncompressionState.Header)
                {
                    #region Header handling
                    //beginning of the stream
                    byte[] beginning = _chunkQueue.DequeueByteBlock(Zlib.GZIP_HEADER_LENGTH);

                    if (beginning == null && !closing)
                    {
                        // we do not have enough data, but we know there would be more data ahead
                        return(new PhpBytes());
                    }
                    else
                    {
                        //check the header format
                        if (beginning.Length >= 2 && beginning[0] == Zlib.GZIP_HEADER[0] && beginning[1] == Zlib.GZIP_HEADER[1])
                        {
                            //header magic bytes are OK
                            if (beginning.Length < Zlib.GZIP_HEADER_LENGTH)
                            {
                                // header is too short -> this is an error
                                PhpException.Throw(PhpError.Warning, "unexpected end of file");
                                return(null);
                            }
                            else
                            {
                                // check the rest of the header
                                if (beginning[2] != Zlib.Z_DEFLATED)
                                {
                                    PhpException.Throw(PhpError.Warning, "unknown compression method");
                                    return(null);
                                }

                                if ((beginning[3] & Zlib.GZIP_HEADER_RESERVED_FLAGS) != 0)
                                {
                                    PhpException.Throw(PhpError.Warning, "unknown header flags set");
                                    return(null);
                                }

                                _headerFlags = beginning[3];

                                //change the header state based on the header flags
                                UpdateHeaderState();
                            }
                        }
                        else
                        {
                            // this is not a gzip format -> passthrough the data
                            _state = UncompressionState.Passthrough;
                            return(new PhpBytes(beginning));
                        }
                    }
                    #endregion
                }

                if (_state == UncompressionState.HeaderExtraField)
                {
                    #region Header Extra Field Handling
                    if (_extraHeaderLength == null)
                    {
                        //length was not yet detected
                        if (_chunkQueue.AvailableBytes < 2)
                        {
                            //wait for more input
                            return(new PhpBytes());
                        }
                        else
                        {
                            //assemble length
                            _extraHeaderLength  = _chunkQueue.DequeueByte();
                            _extraHeaderLength &= (_chunkQueue.DequeueByte() << 8);
                        }
                    }

                    if (_extraHeaderLength != null)
                    {
                        //length was already read
                        if (_chunkQueue.AvailableBytes < _extraHeaderLength)
                        {
                            //wait for more input
                            return(new PhpBytes());
                        }
                        else
                        {
                            Debug.Assert(_extraHeaderLength.HasValue);

                            //skip the extra header
                            _chunkQueue.SkipByteBlock(_extraHeaderLength.Value);

                            UpdateHeaderState();
                        }
                    }
                    #endregion
                }

                if (_state == UncompressionState.HeaderFilename || _state == UncompressionState.HeaderComment)
                {
                    #region Header Filename and Comment Handling
                    // filename or comment

                    // cycle until input ends or zero character is encountered
                    while (true)
                    {
                        byte?nextByte = _chunkQueue.DequeueByte();

                        if (nextByte == null)
                        {
                            //wait for more input
                            return(new PhpBytes());
                        }

                        if (nextByte == 0)
                        {
                            // end the cycle
                            break;
                        }
                    }

                    // go to the next state
                    UpdateHeaderState();
                    #endregion
                }

                if (_state == UncompressionState.HeaderCRC)
                {
                    #region CRC Handling
                    // header CRC

                    if (_chunkQueue.AvailableBytes < 2)
                    {
                        //wait for more input
                        return(new PhpBytes());
                    }
                    else
                    {
                        //skip the CRC
                        _chunkQueue.DequeueByte();
                        _chunkQueue.DequeueByte();

                        UpdateHeaderState();
                    }
                    #endregion
                }

                //filled by data handling and sometimes returned by trailer handling
                byte[] output = null;

                if (_state == UncompressionState.Data)
                {
                    #region Deflated Data Handling

                    //get all available bytes
                    byte[] inputBytes  = _chunkQueue.DequeueByteBlock(_chunkQueue.AvailableBytes);
                    int    inputOffset = 0;

                    // perform the inner operation
                    try
                    {
                        output = FilterInner(inputBytes, ref inputOffset, closing);
                    }
                    catch
                    {
                        // exception was thrown
                        _state = UncompressionState.Failed;
                        throw;
                    }

                    if (output == null)
                    {
                        // error happened and exception was not thrown
                        _state = UncompressionState.Failed;
                        return(null);
                    }

                    // update the hash algorithm
                    _crc.Update(output);

                    if (inputOffset != inputBytes.Length)
                    {
                        // push the rest of the data into the chunk queue
                        _chunkQueue.PushByteBlock(inputBytes, inputOffset, inputBytes.Length - inputOffset);

                        // end of deflated block reached
                        _state = UncompressionState.Trailer;

                        // pass through to Trailer handling
                    }
                    else
                    {
                        //normal decompressed block - return it
                        return(new PhpBytes(output));
                    }

                    #endregion
                }

                if (_state == UncompressionState.Trailer)
                {
                    #region Trailer Handling
                    // the deflate block has already ended, we are processing trailer
                    if (closing || _chunkQueue.AvailableBytes >= Zlib.GZIP_FOOTER_LENGTH)
                    {
                        byte[] trailer;

                        trailer = _chunkQueue.DequeueByteBlock(_chunkQueue.AvailableBytes);

                        if (trailer.Length >= Zlib.GZIP_FOOTER_LENGTH)
                        {
                            byte[] crc = _crc.Final();

                            if (crc[3] != trailer[0] || crc[2] != trailer[1] || crc[1] != trailer[2] || crc[0] != trailer[3])
                            {
                                _state = UncompressionState.Failed;
                                PhpException.Throw(PhpError.Warning, "incorrect data check");
                                return(null);
                            }

                            if (BitConverter.ToInt32(trailer, 4) != _stream.total_out)
                            {
                                _state = UncompressionState.Failed;
                                PhpException.Throw(PhpError.Warning, "incorrect length check");
                                return(null);
                            }

                            _state = closing ? UncompressionState.Finished : UncompressionState.PostTrailer;

                            // everything is fine, return the output if available
                            return(output != null ? new PhpBytes(output) : new PhpBytes());
                        }
                        else
                        {
                            _state = UncompressionState.Failed;
                            PhpException.Throw(PhpError.Warning, "unexpected end of file");
                            return(null);
                        }
                    }
                    else
                    {
                        //stream is not closing yet - return the remaining output, otherwise empty
                        return(output != null ? new PhpBytes(output) : new PhpBytes());
                    }
                    #endregion
                }

                //this should not happen
                Debug.Fail(null);
                return(null);
            }
            else
            {
                Debug.Fail("GzipUncompressionFilter expects chunks to be convertible to PhpBytes.");
                return(null);
            }
        }
예제 #30
0
        public override object Filter(object input, bool closing)
        {
            PhpBytes bInput = Core.Convert.ObjectToPhpBytes(input);

            if (bInput != null)
            {
                if (_state == CompressionState.Failed)
                {
                    PhpException.Throw(PhpError.Warning, "using filter in failed state");
                    return(null);
                }

                if (_state == CompressionState.Finished)
                {
                    PhpException.Throw(PhpError.Warning, "using filter in finished state");
                    return(null);
                }

                byte[] header = null;
                byte[] footer = null;

                if (_state == CompressionState.Header)
                {
                    header    = new byte[Zlib.GZIP_HEADER_LENGTH];
                    header[0] = Zlib.GZIP_HEADER[0];
                    header[1] = Zlib.GZIP_HEADER[1];
                    header[2] = Zlib.Z_DEFLATED;
                    header[3] = 0;
                    // 3-8 represent time and are set to zero
                    header[9] = Zlib.OS_CODE;

                    _crc.Init();

                    _state = CompressionState.Data;
                }

                int    outputOffset = 0;
                byte[] output;

                try
                {
                    output = FilterInner(bInput.ReadonlyData, ref outputOffset, closing);
                }
                catch
                {
                    _state = CompressionState.Failed;
                    throw;
                }

                if (output == null)
                {
                    _state = CompressionState.Failed;
                    return(null);
                }

                // input should be read to the end
                Debug.Assert(outputOffset == bInput.Length);

                _crc.Update(bInput.ReadonlyData);

                if (closing)
                {
                    byte[] crcBytes = _crc.Final();

                    footer = new byte[Zlib.GZIP_FOOTER_LENGTH];

                    // well this implementation simply has the hash inverted compared to C implementation
                    footer[0] = crcBytes[3];
                    footer[1] = crcBytes[2];
                    footer[2] = crcBytes[1];
                    footer[3] = crcBytes[0];

                    footer[4] = (byte)(_stream.total_in & 0xFF);
                    footer[5] = (byte)((_stream.total_in >> 8) & 0xFF);
                    footer[6] = (byte)((_stream.total_in >> 16) & 0xFF);
                    footer[7] = (byte)((_stream.total_in >> 24) & 0xFF);

                    _state = CompressionState.Finished;
                }

                if (header != null || footer != null)
                {
                    int    offset   = 0;
                    byte[] appended = new byte[(header != null ? header.Length : 0) + output.Length + (footer != null ? footer.Length : 0)];

                    if (header != null)
                    {
                        Buffer.BlockCopy(header, 0, appended, 0, header.Length);
                        offset += header.Length;
                    }

                    if (output != null && output.Length > 0)
                    {
                        Buffer.BlockCopy(output, 0, appended, offset, output.Length);
                        offset += output.Length;
                    }

                    if (footer != null)
                    {
                        Buffer.BlockCopy(footer, 0, appended, offset, footer.Length);
                    }

                    return(new PhpBytes(appended));
                }
                else
                {
                    return(new PhpBytes(output));
                }
            }
            else
            {
                Debug.Fail("GzipCompresionFilter expects chunks to be of type PhpBytes.");
                return(null);
            }
        }
예제 #31
0
파일: Literal.cs 프로젝트: Ashod/Phalanger
		/// <summary>
		/// Initializes a new instance of the StringLiteral class.
		/// </summary>
		public BinaryStringLiteral(Position position, PhpBytes/*!*/ value)
			: base(position)
		{
			this.value = value;
		}
예제 #32
0
파일: Literal.cs 프로젝트: Ashod/Phalanger
		/// <summary>
		/// Called only by Analyzer. On this instance Analyze method will not be called.
		/// </summary>
		internal BinaryStringLiteral(Position position, PhpBytes value, AccessType access)
			: base(position)
		{
			this.value = value;
			this.access = access;
		}
예제 #33
0
        public static PhpArray Unpack(string format, PhpBytes data)
        {
            if (format == null)
            {
                return(null);
            }
            byte[] buffer = (data != null) ? data.ReadonlyData : ArrayUtils.EmptyBytes;

            Encoding encoding = Configuration.Application.Globalization.PageEncoding;

            byte[] reversed = new byte[4];             // used for reversing the order of bytes in buffer

            int      i      = 0;
            int      pos    = 0;
            PhpArray result = new PhpArray();

            while (i < format.Length)
            {
                string name;
                int    repeater;
                char   specifier;

                // parses specifier, repeater, and name from the format string:
                ParseFormatToken(format, ref i, out specifier, out repeater, out name);

                int remains = buffer.Length - pos;                          // the number of bytes remaining in the buffer
                int size;                                                   // a size of data to be extracted corresponding to the specifier

                // repeater of '@' specifier has a special meaning:
                if (specifier == '@')
                {
                    if (repeater > buffer.Length || repeater == InfiniteRepeater)
                    {
                        PhpException.Throw(PhpError.Warning, LibResources.GetString("outside_string", specifier));
                    }
                    else
                    {
                        pos = repeater;
                    }

                    continue;
                }

                // number of operations:
                int op_count;

                // gets the size of the data to read and adjust repeater:
                if (!GetSizeToUnpack(specifier, remains, repeater, out op_count, out size))
                {
                    PhpException.Throw(PhpError.Warning, LibResources.GetString("unknown_format_code", specifier));
                    return(null);
                }

                // repeats operation determined by specifier "op_count" times;
                // if op_count is infinite then stops when the number of remaining characters is zero:
                for (int j = 0; j < op_count || op_count == InfiniteRepeater; j++)
                {
                    if (size > remains)
                    {
                        // infinite means "while data are available":
                        if (op_count == InfiniteRepeater)
                        {
                            break;
                        }

                        PhpException.Throw(PhpError.Warning, LibResources.GetString("not_enought_input", specifier, size, remains));
                        return(null);
                    }

                    object item;
                    switch (specifier)
                    {
                    case 'X':                             // decreases position, no value stored:
                        if (pos == 0)
                        {
                            PhpException.Throw(PhpError.Warning, LibResources.GetString("outside_string", specifier));
                        }
                        else
                        {
                            pos--;
                        }
                        continue;

                    case 'x':                             // advances position, no value stored
                        pos++;
                        continue;

                    case 'a':                             // NUL-padded string
                    case 'A':                             // SPACE-padded string
                    {
                        byte pad = (byte)(specifier == 'a' ? 0x00 : 0x20);

                        int last = pos + size - 1;
                        while (last >= pos && buffer[last] == pad)
                        {
                            last--;
                        }

                        item = encoding.GetString(buffer, pos, last - pos + 1);
                        break;
                    }

                    case 'h':                             // Hex string, low/high nibble first - converts to a string, takes n hex digits from string:
                    case 'H':
                    {
                        int p            = pos;
                        int nibble_shift = (specifier == 'h') ? 0 : 4;

                        StringBuilder sb = new StringBuilder(size);
                        for (int k = 0; k < size; k++)
                        {
                            const string hex_digits = "0123456789ABCDEF";

                            sb.Append(hex_digits[(buffer[p] >> nibble_shift) & 0x0f]);

                            // beware of odd repeaters!
                            if (repeater == InfiniteRepeater || repeater > sb.Length)
                            {
                                sb.Append(hex_digits[(buffer[p] >> (4 - nibble_shift)) & 0x0f]);
                            }
                            p++;
                        }

                        item = sb.ToString();
                        break;
                    }

                    case 'c':                             // signed char
                        item = (int)unchecked ((sbyte)buffer[pos]);
                        break;

                    case 'C':                             // unsigned char
                        item = (int)buffer[pos];
                        break;

                    case 's':                             // signed short (always 16 bit, machine byte order)
                        item = (int)BitConverter.ToInt16(buffer, pos);
                        break;

                    case 'S':                             // unsigned short (always 16 bit, machine byte order)
                        item = (int)BitConverter.ToUInt16(buffer, pos);
                        break;

                    case 'n':                             // unsigned short (always 16 bit, big endian byte order)
                        if (BitConverter.IsLittleEndian)
                        {
                            item = (int)BitConverter.ToUInt16(LoadReverseBuffer(reversed, buffer, pos, 2), 0);
                        }
                        else
                        {
                            item = (int)BitConverter.ToUInt16(buffer, pos);
                        }
                        break;

                    case 'v':                             // unsigned short (always 16 bit, little endian byte order)
                        if (!BitConverter.IsLittleEndian)
                        {
                            item = (int)BitConverter.ToUInt16(LoadReverseBuffer(reversed, buffer, pos, 2), 0);
                        }
                        else
                        {
                            item = (int)BitConverter.ToUInt16(buffer, pos);
                        }
                        break;

                    case 'i':                             // signed integer (machine dependent size and byte order - always 32 bit)
                    case 'I':                             // unsigned integer (machine dependent size and byte order - always 32 bit)
                    case 'l':                             // signed long (always 32 bit, machine byte order)
                    case 'L':                             // unsigned long (always 32 bit, machine byte order)
                        item = BitConverter.ToInt32(buffer, pos);
                        break;

                    case 'N':                             // unsigned long (always 32 bit, big endian byte order)
                        item = unchecked (((int)buffer[pos] << 24) + (buffer[pos + 1] << 16) + (buffer[pos + 2] << 8) + buffer[pos + 3]);
                        break;

                    case 'V':                             // unsigned long (always 32 bit, little endian byte order)
                        item = unchecked (((int)buffer[pos + 3] << 24) + (buffer[pos + 2] << 16) + (buffer[pos + 1] << 8) + buffer[pos + 0]);
                        break;

                    case 'f':                             // float (machine dependent size and representation - size is always 4B)
                        item = (double)BitConverter.ToSingle(buffer, pos);
                        break;

                    case 'd':                             // double (machine dependent size and representation - size is always 8B)
                        item = BitConverter.ToDouble(buffer, pos);
                        break;

                    default:
                        Debug.Fail("Invalid specifier.");
                        return(null);
                    }

                    AddValue(result, name, item, op_count, j);

                    pos     += size;
                    remains -= size;
                }
            }

            return(result);
        }