Program: 41376
Project: 41376
Buggy source:
@Override protected void onDraw(Canvas canvas){
  super.onDraw(canvas);
  canvas.save();
  int paddingLeft=getPaddingLeft();
  float xPos=paddingLeft + mBitmap.getWidth() + (2 * IMAGE_BUFFER_PADDING);
  canvas.clipRect(xPos,0,getWidth(),getHeight());
  float offsetX=(Float)mAnimator.getAnimatedValue();
  xPos+=offsetX;
  int baseline=getPaddingTop() + mTextOffsetY - (int)mTextPaint.ascent();
  int length=mNumberFormatted.length();
  if (length == 0) {
    canvas.drawText(NUMBER_HINT,xPos,baseline,mHintPaint);
  }
 else {
    if ((mError) && (mMode == Mode.NUMBER)) {
      canvas.drawText(mNumberFormatted,0,length,xPos,baseline,mErrorPaint);
    }
 else {
      canvas.drawText(mNumberFormatted,0,length,xPos,baseline,mTextPaint);
    }
  }
  if (mMode != Mode.NUMBER) {
    if (mExpiryFormatted.length() == 0) {
      canvas.drawText(EXPIRY_HINT,mExpiryOffset + offsetX,baseline,mHintPaint);
      canvas.drawText(CVC_HINT,mCVCOffset + offsetX,baseline,mHintPaint);
    }
 else {
      if ((mError) && ((mMode == Mode.EXPIRYYEAR) || (mMode == Mode.EXPIRYMONTH))) {
        canvas.drawText(mExpiryFormatted,0,mExpiryFormatted.length(),mExpiryOffset + offsetX,baseline,mErrorPaint);
      }
 else {
        canvas.drawText(mExpiryFormatted,0,mExpiryFormatted.length(),mExpiryOffset + offsetX,baseline,mTextPaint);
      }
      if (mCVC.length() == 0) {
        canvas.drawText(CVC_HINT,mCVCOffset + offsetX,baseline,mHintPaint);
      }
 else {
        canvas.drawText(mCVC,0,mCVC.length(),mCVCOffset + offsetX,baseline,mTextPaint);
      }
    }
  }
  canvas.restore();
  if (mMode == Mode.CVC) {
    float yPos=(getMeasuredHeight() - mCVCBitmap.getHeight()) / 2;
    canvas.drawBitmap(mCVCBitmap,IMAGE_BUFFER_PADDING + paddingLeft,yPos,mBitmapPaint);
  }
 else {
    float yPos=(getMeasuredHeight() - mBitmap.getHeight()) / 2;
    canvas.drawBitmap(mBitmap,IMAGE_BUFFER_PADDING + paddingLeft,yPos,mBitmapPaint);
  }
  if (mCursorOn) {
    float cursorPosition;
switch (mMode) {
case NUMBER:
      cursorPosition=mTextPaint.measureText(mNumberFormatted,0,mNumberFormatted.length());
    cursorPosition+=xPos;
  break;
case EXPIRYMONTH:
case EXPIRYYEAR:
cursorPosition=mTextPaint.measureText(mExpiryFormatted,0,mExpiryFormatted.length());
cursorPosition+=mExpiryOffset + offsetX;
break;
default :
cursorPosition=mTextPaint.measureText(mCVC,0,mCVC.length());
cursorPosition+=mCVCOffset + offsetX;
}
Paint.FontMetrics metrics=mTextPaint.getFontMetrics();
canvas.drawRect(cursorPosition,baseline + metrics.top,cursorPosition + 1,baseline + metrics.descent,mTextPaint);
}
}

Fixed version (ground truth):
@Override protected void onDraw(Canvas canvas){
  super.onDraw(canvas);
  canvas.save();
  int paddingLeft=getPaddingLeft();
  float xPos=paddingLeft + mBitmap.getWidth() + (2 * IMAGE_BUFFER_PADDING);
  canvas.clipRect(xPos,0,getWidth(),getHeight());
  float offsetX=(Float)mAnimator.getAnimatedValue();
  xPos+=offsetX;
  int baseline=getPaddingTop() + mTextOffsetY - (int)mTextPaint.ascent();
  int length=mNumberFormatted.length();
  if (length == 0) {
    canvas.drawText(NUMBER_HINT,xPos,baseline,mHintPaint);
  }
 else {
    if ((mError) && (mMode == Mode.NUMBER)) {
      canvas.drawText(mNumberFormatted,0,length,xPos,baseline,mErrorPaint);
    }
 else {
      canvas.drawText(mNumberFormatted,0,length,xPos,baseline,mTextPaint);
    }
  }
  if (mMode != Mode.NUMBER) {
    if (mExpiryFormatted.length() == 0) {
      canvas.drawText(EXPIRY_HINT,mExpiryOffset + offsetX,baseline,mHintPaint);
      canvas.drawText(mCardType.mCVCHint,mCVCOffset + offsetX,baseline,mHintPaint);
    }
 else {
      if ((mError) && ((mMode == Mode.EXPIRYYEAR) || (mMode == Mode.EXPIRYMONTH))) {
        canvas.drawText(mExpiryFormatted,0,mExpiryFormatted.length(),mExpiryOffset + offsetX,baseline,mErrorPaint);
      }
 else {
        canvas.drawText(mExpiryFormatted,0,mExpiryFormatted.length(),mExpiryOffset + offsetX,baseline,mTextPaint);
      }
      if (mCVC.length() == 0) {
        canvas.drawText(mCardType.mCVCHint,mCVCOffset + offsetX,baseline,mHintPaint);
      }
 else {
        canvas.drawText(mCVC,0,mCVC.length(),mCVCOffset + offsetX,baseline,mTextPaint);
      }
    }
  }
  canvas.restore();
  if (mMode == Mode.CVC) {
    float yPos=(getMeasuredHeight() - mCVCBitmap.getHeight()) / 2;
    canvas.drawBitmap(mCVCBitmap,IMAGE_BUFFER_PADDING + paddingLeft,yPos,mBitmapPaint);
  }
 else {
    float yPos=(getMeasuredHeight() - mBitmap.getHeight()) / 2;
    canvas.drawBitmap(mBitmap,IMAGE_BUFFER_PADDING + paddingLeft,yPos,mBitmapPaint);
  }
  if (mCursorOn) {
    float cursorPosition;
switch (mMode) {
case NUMBER:
      cursorPosition=mTextPaint.measureText(mNumberFormatted,0,mNumberFormatted.length());
    cursorPosition+=xPos;
  break;
case EXPIRYMONTH:
case EXPIRYYEAR:
cursorPosition=mTextPaint.measureText(mExpiryFormatted,0,mExpiryFormatted.length());
cursorPosition+=mExpiryOffset + offsetX;
break;
default :
cursorPosition=mTextPaint.measureText(mCVC,0,mCVC.length());
cursorPosition+=mCVCOffset + offsetX;
}
Paint.FontMetrics metrics=mTextPaint.getFontMetrics();
canvas.drawRect(cursorPosition,baseline + metrics.top,cursorPosition + 1,baseline + metrics.descent,mTextPaint);
}
}