Example #1
0
        public static void HandleCorruptObject
        (
            this Activity thisActivity,
            CorruptObjectException imageException,
            ImageView imageView,
            Func <byte> getCount   = null,
            Action <byte> setCount = null
        )
        {
            if ((getCount != null) && (setCount == null))
            {
                throw new ArgumentNullException(nameof(setCount));
            }
            else if ((getCount == null) && (setCount != null))
            {
                throw new ArgumentNullException(nameof(getCount));
            }
            else if ((getCount != null) && (setCount != null))
            {
                byte currentCount = getCount();

                if (currentCount == 0)
                {
                    return;
                }

                setCount(--currentCount);
            }

            imageView.SetImageResource(Resource.Drawable.CorruptObject);

            string exceptionFormat  = thisActivity.GetString(Resource.String.CorruptObjectFormat);
            string exceptionMessage = string.Format(exceptionFormat,
                                                    imageException.Message);

            Toast.MakeText
            (
                thisActivity,
                exceptionMessage,
                ToastLength.Long
            )
            .Show();
        }
        private void Decompress(AnyObjectId id, Inflater inf, int p)
        {
            try
            {
                while (!inf.IsFinished)
                {
                    p += inf.Inflate(_bytes, p, _objectSize - p);
                }
            }
            catch (IOException dfe)
            {
                var coe = new CorruptObjectException(id, "bad stream", dfe);
                throw coe;
            }

            if (p != _objectSize)
            {
                throw new CorruptObjectException(id, "incorrect Length");
            }
        }
Example #3
0
        /// <exception cref="System.IO.IOException"></exception>
        internal virtual ObjectLoader Load(WindowCursor curs, long pos)
        {
            try
            {
                byte[]         ib     = curs.tempId;
                PackFile.Delta delta  = null;
                byte[]         data   = null;
                int            type   = Constants.OBJ_BAD;
                bool           cached = false;
                for (; ;)
                {
                    ReadFully(pos, ib, 0, 20, curs);
                    int  c        = ib[0] & unchecked ((int)(0xff));
                    int  typeCode = (c >> 4) & 7;
                    long sz       = c & 15;
                    int  shift    = 4;
                    int  p        = 1;
                    while ((c & unchecked ((int)(0x80))) != 0)
                    {
                        c      = ib[p++] & unchecked ((int)(0xff));
                        sz    += ((long)(c & unchecked ((int)(0x7f)))) << shift;
                        shift += 7;
                    }
                    switch (typeCode)
                    {
                    case Constants.OBJ_COMMIT:
                    case Constants.OBJ_TREE:
                    case Constants.OBJ_BLOB:
                    case Constants.OBJ_TAG:
                    {
                        if (sz < curs.GetStreamFileThreshold())
                        {
                            data = Decompress(pos + p, (int)sz, curs);
                        }
                        if (delta != null)
                        {
                            type = typeCode;
                            goto SEARCH_break;
                        }
                        if (data != null)
                        {
                            return(new ObjectLoader.SmallObject(typeCode, data));
                        }
                        else
                        {
                            return(new LargePackedWholeObject(typeCode, sz, pos, p, this, curs.db));
                        }
                        goto case Constants.OBJ_OFS_DELTA;
                    }

                    case Constants.OBJ_OFS_DELTA:
                    {
                        c = ib[p++] & unchecked ((int)(0xff));
                        long @base = c & 127;
                        while ((c & 128) != 0)
                        {
                            @base  += 1;
                            c       = ib[p++] & unchecked ((int)(0xff));
                            @base <<= 7;
                            @base  += (c & 127);
                        }
                        @base = pos - @base;
                        delta = new PackFile.Delta(delta, pos, (int)sz, p, @base);
                        if (sz != delta.deltaSize)
                        {
                            goto SEARCH_break;
                        }
                        DeltaBaseCache.Entry e = curs.GetDeltaBaseCache().Get(this, @base);
                        if (e != null)
                        {
                            type   = e.type;
                            data   = e.data;
                            cached = true;
                            goto SEARCH_break;
                        }
                        pos = @base;
                        goto SEARCH_continue;
                    }

                    case Constants.OBJ_REF_DELTA:
                    {
                        ReadFully(pos + p, ib, 0, 20, curs);
                        long @base = FindDeltaBase(ObjectId.FromRaw(ib));
                        delta = new PackFile.Delta(delta, pos, (int)sz, p + 20, @base);
                        if (sz != delta.deltaSize)
                        {
                            goto SEARCH_break;
                        }
                        DeltaBaseCache.Entry e = curs.GetDeltaBaseCache().Get(this, @base);
                        if (e != null)
                        {
                            type   = e.type;
                            data   = e.data;
                            cached = true;
                            goto SEARCH_break;
                        }
                        pos = @base;
                        goto SEARCH_continue;
                    }

                    default:
                    {
                        throw new IOException(MessageFormat.Format(JGitText.Get().unknownObjectType, Sharpen.Extensions.ValueOf
                                                                       (typeCode)));
                    }
                    }
                    SEARCH_continue :;
                }
                SEARCH_break :;
                // At this point there is at least one delta to apply to data.
                // (Whole objects with no deltas to apply return early above.)
                if (data == null)
                {
                    return(delta.Large(this, curs));
                }
                do
                {
                    // Cache only the base immediately before desired object.
                    if (cached)
                    {
                        cached = false;
                    }
                    else
                    {
                        if (delta.next == null)
                        {
                            curs.GetDeltaBaseCache().Store(this, delta.basePos, data, type);
                        }
                    }
                    pos = delta.deltaPos;
                    byte[] cmds = Decompress(pos + delta.hdrLen, delta.deltaSize, curs);
                    if (cmds == null)
                    {
                        data = null;
                        // Discard base in case of OutOfMemoryError
                        return(delta.Large(this, curs));
                    }
                    long sz = BinaryDelta.GetResultSize(cmds);
                    if (int.MaxValue <= sz)
                    {
                        return(delta.Large(this, curs));
                    }
                    byte[] result;
                    try
                    {
                        result = new byte[(int)sz];
                    }
                    catch (OutOfMemoryException)
                    {
                        data = null;
                        // Discard base in case of OutOfMemoryError
                        return(delta.Large(this, curs));
                    }
                    BinaryDelta.Apply(data, cmds, result);
                    data  = result;
                    delta = delta.next;
                }while (delta != null);
                return(new ObjectLoader.SmallObject(type, data));
            }
            catch (SharpZipBaseException dfe)
            {
                CorruptObjectException coe = new CorruptObjectException(MessageFormat.Format(JGitText
                                                                                             .Get().objectAtHasBadZlibStream, Sharpen.Extensions.ValueOf(pos), GetPackFile())
                                                                        );
                Sharpen.Extensions.InitCause(coe, dfe);
                throw coe;
            }
        }
Example #4
0
        /// <exception cref="System.IO.IOException"></exception>
        /// <exception cref="NGit.Errors.StoredObjectRepresentationNotAvailableException"></exception>
        private void CopyAsIs2(PackOutputStream @out, LocalObjectToPack src, bool validate
                               , WindowCursor curs)
        {
            CRC32 crc1 = validate ? new CRC32() : null;
            CRC32 crc2 = validate ? new CRC32() : null;

            byte[] buf = @out.GetCopyBuffer();
            // Rip apart the header so we can discover the size.
            //
            ReadFully(src.offset, buf, 0, 20, curs);
            int  c              = buf[0] & unchecked ((int)(0xff));
            int  typeCode       = (c >> 4) & 7;
            long inflatedLength = c & 15;
            int  shift          = 4;
            int  headerCnt      = 1;

            while ((c & unchecked ((int)(0x80))) != 0)
            {
                c = buf[headerCnt++] & unchecked ((int)(0xff));
                inflatedLength += ((long)(c & unchecked ((int)(0x7f)))) << shift;
                shift          += 7;
            }
            if (typeCode == Constants.OBJ_OFS_DELTA)
            {
                do
                {
                    c = buf[headerCnt++] & unchecked ((int)(0xff));
                }while ((c & 128) != 0);
                if (validate)
                {
                    crc1.Update(buf, 0, headerCnt);
                    crc2.Update(buf, 0, headerCnt);
                }
            }
            else
            {
                if (typeCode == Constants.OBJ_REF_DELTA)
                {
                    if (validate)
                    {
                        crc1.Update(buf, 0, headerCnt);
                        crc2.Update(buf, 0, headerCnt);
                    }
                    ReadFully(src.offset + headerCnt, buf, 0, 20, curs);
                    if (validate)
                    {
                        crc1.Update(buf, 0, 20);
                        crc2.Update(buf, 0, 20);
                    }
                    headerCnt += 20;
                }
                else
                {
                    if (validate)
                    {
                        crc1.Update(buf, 0, headerCnt);
                        crc2.Update(buf, 0, headerCnt);
                    }
                }
            }
            long            dataOffset = src.offset + headerCnt;
            long            dataLength = src.length;
            long            expectedCRC;
            ByteArrayWindow quickCopy;

            // Verify the object isn't corrupt before sending. If it is,
            // we report it missing instead.
            //
            try
            {
                quickCopy = curs.QuickCopy(this, dataOffset, dataLength);
                if (validate && Idx().HasCRC32Support())
                {
                    // Index has the CRC32 code cached, validate the object.
                    //
                    expectedCRC = Idx().FindCRC32(src);
                    if (quickCopy != null)
                    {
                        quickCopy.Crc32(crc1, dataOffset, (int)dataLength);
                    }
                    else
                    {
                        long pos = dataOffset;
                        long cnt = dataLength;
                        while (cnt > 0)
                        {
                            int n = (int)Math.Min(cnt, buf.Length);
                            ReadFully(pos, buf, 0, n, curs);
                            crc1.Update(buf, 0, n);
                            pos += n;
                            cnt -= n;
                        }
                    }
                    if (crc1.GetValue() != expectedCRC)
                    {
                        SetCorrupt(src.offset);
                        throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().objectAtHasBadZlibStream
                                                                              , Sharpen.Extensions.ValueOf(src.offset), GetPackFile()));
                    }
                }
                else
                {
                    if (validate)
                    {
                        // We don't have a CRC32 code in the index, so compute it
                        // now while inflating the raw data to get zlib to tell us
                        // whether or not the data is safe.
                        //
                        Inflater inf = curs.Inflater();
                        byte[]   tmp = new byte[1024];
                        if (quickCopy != null)
                        {
                            quickCopy.Check(inf, tmp, dataOffset, (int)dataLength);
                        }
                        else
                        {
                            long pos = dataOffset;
                            long cnt = dataLength;
                            while (cnt > 0)
                            {
                                int n = (int)Math.Min(cnt, buf.Length);
                                ReadFully(pos, buf, 0, n, curs);
                                crc1.Update(buf, 0, n);
                                inf.SetInput(buf, 0, n);
                                while (inf.Inflate(tmp, 0, tmp.Length) > 0)
                                {
                                    continue;
                                }
                                pos += n;
                                cnt -= n;
                            }
                        }
                        if (!inf.IsFinished || inf.TotalIn != dataLength)
                        {
                            SetCorrupt(src.offset);
                            throw new EOFException(MessageFormat.Format(JGitText.Get().shortCompressedStreamAt
                                                                        , Sharpen.Extensions.ValueOf(src.offset)));
                        }
                        expectedCRC = crc1.GetValue();
                    }
                    else
                    {
                        expectedCRC = -1;
                    }
                }
            }
            catch (SharpZipBaseException dataFormat)
            {
                SetCorrupt(src.offset);
                CorruptObjectException corruptObject = new CorruptObjectException(MessageFormat.Format
                                                                                      (JGitText.Get().objectAtHasBadZlibStream, Sharpen.Extensions.ValueOf(src.offset)
                                                                                      , GetPackFile()));
                Sharpen.Extensions.InitCause(corruptObject, dataFormat);
                StoredObjectRepresentationNotAvailableException gone;
                gone = new StoredObjectRepresentationNotAvailableException(src);
                Sharpen.Extensions.InitCause(gone, corruptObject);
                throw gone;
            }
            catch (IOException ioError)
            {
                StoredObjectRepresentationNotAvailableException gone;
                gone = new StoredObjectRepresentationNotAvailableException(src);
                Sharpen.Extensions.InitCause(gone, ioError);
                throw gone;
            }
            if (quickCopy != null)
            {
                // The entire object fits into a single byte array window slice,
                // and we have it pinned.  Write this out without copying.
                //
                @out.WriteHeader(src, inflatedLength);
                quickCopy.Write(@out, dataOffset, (int)dataLength, null);
            }
            else
            {
                if (dataLength <= buf.Length)
                {
                    // Tiny optimization: Lots of objects are very small deltas or
                    // deflated commits that are likely to fit in the copy buffer.
                    //
                    if (!validate)
                    {
                        long pos = dataOffset;
                        long cnt = dataLength;
                        while (cnt > 0)
                        {
                            int n = (int)Math.Min(cnt, buf.Length);
                            ReadFully(pos, buf, 0, n, curs);
                            pos += n;
                            cnt -= n;
                        }
                    }
                    @out.WriteHeader(src, inflatedLength);
                    @out.Write(buf, 0, (int)dataLength);
                }
                else
                {
                    // Now we are committed to sending the object. As we spool it out,
                    // check its CRC32 code to make sure there wasn't corruption between
                    // the verification we did above, and us actually outputting it.
                    //
                    @out.WriteHeader(src, inflatedLength);
                    long pos = dataOffset;
                    long cnt = dataLength;
                    while (cnt > 0)
                    {
                        int n = (int)Math.Min(cnt, buf.Length);
                        ReadFully(pos, buf, 0, n, curs);
                        if (validate)
                        {
                            crc2.Update(buf, 0, n);
                        }
                        @out.Write(buf, 0, n);
                        pos += n;
                        cnt -= n;
                    }
                    if (validate && crc2.GetValue() != expectedCRC)
                    {
                        throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().objectAtHasBadZlibStream
                                                                              , Sharpen.Extensions.ValueOf(src.offset), GetPackFile()));
                    }
                }
            }
        }
        private UnpackedObjectLoader(byte[] compressed, AnyObjectId id)
        {
            // Try to determine if this is a legacy format loose object or
            // a new style loose object. The legacy format was completely
            // compressed with zlib so the first byte must be 0x78 (15-bit
            // window size, deflated) and the first 16 bit word must be
            // evenly divisible by 31. Otherwise its a new style loose
            // object.
            //
            Inflater inflater = InflaterCache.Instance.get();

            try
            {
                int fb = compressed[0] & 0xff;
                if (fb == 0x78 && (((fb << 8) | compressed[1] & 0xff) % 31) == 0)
                {
                    inflater.SetInput(compressed);
                    var hdr   = new byte[64];
                    int avail = 0;
                    while (!inflater.IsFinished && avail < hdr.Length)
                    {
                        try
                        {
                            avail += inflater.Inflate(hdr, avail, hdr.Length - avail);
                        }
                        catch (IOException dfe)
                        {
                            var coe = new CorruptObjectException(id, "bad stream", dfe);
                            //inflater.end();
                            throw coe;
                        }
                    }

                    if (avail < 5)
                    {
                        throw new CorruptObjectException(id, "no header");
                    }

                    var p = new MutableInteger();
                    _objectType = Constants.decodeTypeString(id, hdr, (byte)' ', p);
                    _objectSize = RawParseUtils.parseBase10(hdr, p.value, p);

                    if (_objectSize < 0)
                    {
                        throw new CorruptObjectException(id, "negative size");
                    }

                    if (hdr[p.value++] != 0)
                    {
                        throw new CorruptObjectException(id, "garbage after size");
                    }

                    _bytes = new byte[_objectSize];

                    if (p.value < avail)
                    {
                        Array.Copy(hdr, p.value, _bytes, 0, avail - p.value);
                    }

                    Decompress(id, inflater, avail - p.value);
                }
                else
                {
                    int p        = 0;
                    int c        = compressed[p++] & 0xff;
                    int typeCode = (c >> 4) & 7;
                    int size     = c & 15;
                    int shift    = 4;
                    while ((c & 0x80) != 0)
                    {
                        c      = compressed[p++] & 0xff;
                        size  += (c & 0x7f) << shift;
                        shift += 7;
                    }

                    switch (typeCode)
                    {
                    case Constants.OBJ_COMMIT:
                    case Constants.OBJ_TREE:
                    case Constants.OBJ_BLOB:
                    case Constants.OBJ_TAG:
                        _objectType = typeCode;
                        break;

                    default:
                        throw new CorruptObjectException(id, "invalid type");
                    }

                    _objectSize = size;
                    _bytes      = new byte[_objectSize];
                    inflater.SetInput(compressed, p, compressed.Length - p);
                    Decompress(id, inflater, 0);
                }
            }
            finally
            {
                InflaterCache.Instance.release(inflater);
            }
        }
        private static async Task RenderThumbnailAsync
        (
            this PortableAsyncRenderer <Bitmap> asyncRenderer,
            PortableCorrelatedEntity correlatedEntity,
            Action <Action> runOnUiThread,
            AndroidCachingImageView thumbnailView,
            int thumbnailWidth,
            int thumbnailHeight,
            Resources activityResources,
            Drawable originalBackground,
            AnimationDrawable loadingAnimation,
            Action <CorruptObjectException, ImageView> onCorrupt,
            Action <ImageView, Drawable, AnimationDrawable, bool> onFinished
        )
        {
            bool isLoaded = false;

            if (correlatedEntity.CorrelationTag != thumbnailView.GetCorrelationTag())
            {
                onFinished?.Invoke(thumbnailView,
                                   originalBackground,
                                   loadingAnimation,
                                   isLoaded);
                return;
            }

            Bitmap thumbnailBitmap = null;
            CorruptObjectException thumbnailException = null;

            BitmapDrawable thumbnailDrawable = AndroidCrapApplication.GetDrawableFromCache
                                               (
                correlatedEntity.CorrelationTag
                                               );

            if (thumbnailDrawable == null)
            {
                try
                {
                    /*thumbnailDrawable = AndroidCrapApplication.GetReusableBitmapDrawable(thumbnailWidth,
                     *                                                                   thumbnailHeight);*/
                    thumbnailBitmap = await asyncRenderer.GetThumbnailAsync
                                      (
                        correlatedEntity,
                        () => thumbnailView.GetCorrelationTag(),
                        thumbnailWidth,
                        thumbnailHeight//,
                        //thumbnailDrawable.Bitmap
                                      );
                }
                catch (Exception exception)
                {
                    AndroidCrapApplication.ApplicationLogger.LogError(exception);
                    thumbnailBitmap?.Dispose();

                    thumbnailException = exception as CorruptObjectException;

                    if (thumbnailException == null)
                    {
                        throw;
                    }
                    else
                    {
                        runOnUiThread
                        (
                            () => onCorrupt(thumbnailException,
                                            thumbnailView)
                        );
                    }

                    onFinished?.Invoke(thumbnailView,
                                       originalBackground,
                                       loadingAnimation,
                                       isLoaded);
                    return;
                }

                if (correlatedEntity.CorrelationTag != thumbnailView.GetCorrelationTag())
                {
                    thumbnailBitmap?.Dispose();

                    onFinished?.Invoke(thumbnailView,
                                       originalBackground,
                                       loadingAnimation,
                                       isLoaded);
                    return;
                }

                if (thumbnailBitmap == null)
                {
                    onFinished?.Invoke(thumbnailView,
                                       originalBackground,
                                       loadingAnimation,
                                       isLoaded);
                    return;
                }

                thumbnailDrawable = AndroidCrapApplication.AddBitmapToCache
                                    (
                    correlatedEntity.CorrelationTag,
                    thumbnailBitmap,
                    activityResources
                                    );
            }

            isLoaded = true;

            onFinished?.Invoke(thumbnailView,
                               originalBackground,
                               loadingAnimation,
                               isLoaded);
            runOnUiThread
            (
                () => { thumbnailView.SetImageDrawable(thumbnailDrawable); }
            );

            /*AndroidCrapApplication.ApplicationLogger.LogDebug("{0} : {1}",
             *                                                correlatedEntity.CorrelationTag,
             *                                                GC.GetTotalMemory(false));*/
        }
Example #7
0
        private async void LoadImageAsync()
        {
            if (_deviceOrientation == null)
            {
                _deviceOrientation = Intent.GetIntExtra(DeviceOrientationExtra,
                                                        OrientationEventListener.OrientationUnknown);
            }

            if (_deviceOrientation == OrientationEventListener.OrientationUnknown)
            {
                _deviceOrientation = 0;
            }

            // http://stackoverflow.com/questions/20902775/how-to-check-if-auto-rotate-screen-setting-is-on-off-in-android-4-0
            bool autoRotation = (Settings.System.GetInt(ContentResolver,
                                                        Settings.System.AccelerometerRotation, 0) == 1);

            int pictureOrientation = await AndroidExifHandler.GetPictureOrientationAsync(_picturePath);

            if (autoRotation == false)
            {
                pictureOrientation += (360 - _deviceOrientation.Value) % 360;
            }

            int viewWidth  = _imageView.Width;
            int viewHeight = _imageView.Height;

            DisplayMetrics displayMetrics = Resources.DisplayMetrics;
            double         displayWidth   = displayMetrics.WidthPixels;
            var            displayHeight  = displayMetrics.HeightPixels;

            Size bitmapSize = await AndroidBitmapHandler.GetBitmapSizeAsync(_picturePath);

            int imageWidth  = bitmapSize.Width;
            int imageHeight = bitmapSize.Height;

            // when auto-rotation switched off, image view rectangle may be 'wrongly rotated' for
            // the image width / height as saved (without taking picture rotation flag into account):
            if ((autoRotation == false) ||
                ((displayWidth - displayHeight) * (imageWidth - imageHeight) < 0))
            {
                viewWidth  = _imageView.Height;
                viewHeight = _imageView.Width;
            }

            Bitmap imageBitmap = null;
            CorruptObjectException imageException = null;

            try
            {
                // resize the bitmap to fit the display - loading the full sized image will consume too much memory:
                imageBitmap = await AndroidBitmapHandler.LoadAdjustedBitmapAsync
                              (
                    _picturePath,
                    viewWidth,
                    viewHeight,
                    pictureOrientation
                              );
            }
            catch (Exception exception)
            {
                imageException = exception as CorruptObjectException;

                if (imageException == null)
                {
                    throw;
                }
            }

            RunOnUiThread
            (
                () =>

            {
                if (imageException != null)
                {
                    this.HandleCorruptObject(imageException,
                                             _imageView);
                }
                else
                {
                    using (imageBitmap)
                    {
                        _imageView.SetImageBitmap(imageBitmap);
                    }

                    imageBitmap = null;

                    _attributesButton.Visibility = ViewStates.Visible;
                    _rotateButton.Visibility     = ViewStates.Visible;
                }
            }
            );
        }