From 258cb228c636282a3e4f4ce87b1017498e207f33 Mon Sep 17 00:00:00 2001 From: "reed@android.com" Date: Wed, 14 Apr 2010 13:36:33 +0000 Subject: [PATCH] fix overflow in matrixproc, and add debugging code to test that git-svn-id: http://skia.googlecode.com/svn/trunk@548 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/core/SkBitmapProcShader.cpp | 25 ++++++++++++++++++++-- src/core/SkBitmapProcState.cpp | 11 ++++++---- src/core/SkBitmapProcState.h | 9 ++++---- src/core/SkBitmapProcState_matrixProcs.cpp | 2 +- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index bd4fece96..c3fd7d027 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -137,6 +137,15 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device, #define BUF_MAX 128 +#define TEST_BUFFER_OVERRITEx + +#ifdef TEST_BUFFER_OVERRITE + #define TEST_BUFFER_EXTRA 32 + #define TEST_PATTERN 0x88888888 +#else + #define TEST_BUFFER_EXTRA 0 +#endif + void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { const SkBitmapProcState& state = fState; if (state.fShaderProc32) { @@ -144,10 +153,10 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { return; } - uint32_t buffer[BUF_MAX]; + uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; SkBitmapProcState::MatrixProc mproc = state.fMatrixProc; SkBitmapProcState::SampleProc32 sproc = state.fSampleProc32; - int max = fState.maxCountForBufferSize(sizeof(buffer)); + int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); SkASSERT(state.fBitmap->getPixels()); SkASSERT(state.fBitmap->pixelRef() == NULL || @@ -158,12 +167,24 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { if (n > max) { n = max; } + SkASSERT(n > 0 && n < BUF_MAX*2); +#ifdef TEST_BUFFER_OVERRITE + for (int i = 0; i < TEST_BUFFER_EXTRA; i++) { + buffer[BUF_MAX + i] = TEST_PATTERN; + } +#endif mproc(state, buffer, n, x, y); +#ifdef TEST_BUFFER_OVERRITE + for (int j = 0; j < TEST_BUFFER_EXTRA; j++) { + SkASSERT(buffer[BUF_MAX + j] == TEST_PATTERN); + } +#endif sproc(state, buffer, n, dstC); if ((count -= n) == 0) { break; } + SkASSERT(count > 0); x += n; dstC += n; } diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index eabd9665e..e54818d03 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -543,7 +543,6 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { */ int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const { int32_t size = static_cast(bufferSize); - int perElemShift; size &= ~3; // only care about 4-byte aligned chunks if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { @@ -551,11 +550,15 @@ int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const { if (size < 0) { size = 0; } - perElemShift = fDoFilter ? 2 : 1; + size >>= 1; } else { - perElemShift = fDoFilter ? 3 : 2; + size >>= 2; } - return size >> perElemShift; + if (fDoFilter) { + size >>= 1; + } + + return size; } diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h index dd73c33c6..303696f46 100644 --- a/src/core/SkBitmapProcState.h +++ b/src/core/SkBitmapProcState.h @@ -91,10 +91,11 @@ struct SkBitmapProcState { */ void platformProcs(); - /** Given the size of a buffer, to be used for calling the matrix and - sample procs, this return the maximum count that can be stored in the - buffer, taking into account that filtering and scale-vs-affine affect - this value. + /** Given the byte size of the index buffer to be passed to the matrix proc, + return the maximum number of resulting pixels that can be computed + (i.e. the number of SkPMColor values to be written by the sample proc). + This routine takes into account that filtering and scale-vs-affine + affect the amount of buffer space needed. Only valid to call after chooseProcs (setContext) has been called. It is safe to call this inside the shader's shadeSpan() method. diff --git a/src/core/SkBitmapProcState_matrixProcs.cpp b/src/core/SkBitmapProcState_matrixProcs.cpp index 6654312a8..d0bc8d814 100644 --- a/src/core/SkBitmapProcState_matrixProcs.cpp +++ b/src/core/SkBitmapProcState_matrixProcs.cpp @@ -368,7 +368,7 @@ static void clampx_nofilter_trans(const SkBitmapProcState& s, } // fill the remaining with the max value - sk_memset16(xptr, width - 1, count * sizeof(uint16_t)); + sk_memset16(xptr, width - 1, count); } static void repeatx_nofilter_trans(const SkBitmapProcState& s,