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"); } }
/// <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; } }
/// <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));*/ }
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; } } ); }