Program: 191042
Project: 191042
Buggy source:
/** 
 * Validate internal set of accounts against installed authenticators for given user. Clear cached authenticators before validating when requested.
 */
private void validateAccountsInternal(UserAccounts accounts,boolean invalidateAuthenticatorCache){
  if (Log.isLoggable(TAG,Log.DEBUG)) {
    Log.d(TAG,"String_Node_Str" + accounts.userId + "String_Node_Str"+ accounts.openHelper.isCeDatabaseAttached()+ "String_Node_Str"+ mLocalUnlockedUsers.get(accounts.userId));
  }
  if (invalidateAuthenticatorCache) {
    mAuthenticatorCache.invalidateCache(accounts.userId);
  }
  final HashMap<String,Integer> knownAuth=getAuthenticatorTypeAndUIDForUser(mAuthenticatorCache,accounts.userId);
  boolean userUnlocked=isLocalUnlockedUser(accounts.userId);
synchronized (accounts.cacheLock) {
    final SQLiteDatabase db=accounts.openHelper.getWritableDatabase();
    boolean accountDeleted=false;
    Cursor metaCursor=db.query(TABLE_META,new String[]{META_KEY,META_VALUE},SELECTION_META_BY_AUTHENTICATOR_TYPE,new String[]{META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + "String_Node_Str"},null,null,META_KEY);
    HashSet<String> obsoleteAuthType=Sets.newHashSet();
    try {
      SparseBooleanArray knownUids=null;
      while (metaCursor.moveToNext()) {
        String type=TextUtils.split(metaCursor.getString(0),META_KEY_DELIMITER)[1];
        String uid=metaCursor.getString(1);
        if (TextUtils.isEmpty(type) || TextUtils.isEmpty(uid)) {
          Slog.e(TAG,"String_Node_Str" + TextUtils.isEmpty(type) + "String_Node_Str"+ TextUtils.isEmpty(uid));
          continue;
        }
        Integer knownUid=knownAuth.get(type);
        if (knownUid != null && uid.equals(knownUid.toString())) {
          knownAuth.remove(type);
        }
 else {
          if (knownUids == null) {
            knownUids=getUidsOfInstalledOrUpdatedPackagesAsUser(accounts.userId);
          }
          if (!knownUids.get(Integer.parseInt(uid))) {
            obsoleteAuthType.add(type);
            db.delete(TABLE_META,META_KEY + "String_Node_Str" + META_VALUE+ "String_Node_Str",new String[]{META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + type,uid});
          }
        }
      }
    }
  finally {
      metaCursor.close();
    }
    Iterator<Entry<String,Integer>> iterator=knownAuth.entrySet().iterator();
    while (iterator.hasNext()) {
      Entry<String,Integer> entry=iterator.next();
      ContentValues values=new ContentValues();
      values.put(META_KEY,META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + entry.getKey());
      values.put(META_VALUE,entry.getValue());
      db.insertWithOnConflict(TABLE_META,null,values,SQLiteDatabase.CONFLICT_REPLACE);
    }
    Cursor cursor=db.query(TABLE_ACCOUNTS,new String[]{ACCOUNTS_ID,ACCOUNTS_TYPE,ACCOUNTS_NAME},null,null,null,null,ACCOUNTS_ID);
    try {
      accounts.accountCache.clear();
      final HashMap<String,ArrayList<String>> accountNamesByType=new LinkedHashMap<>();
      while (cursor.moveToNext()) {
        final long accountId=cursor.getLong(0);
        final String accountType=cursor.getString(1);
        final String accountName=cursor.getString(2);
        if (obsoleteAuthType.contains(accountType)) {
          Slog.w(TAG,"String_Node_Str" + accountName + "String_Node_Str"+ accountType+ "String_Node_Str");
          db.beginTransaction();
          try {
            db.delete(TABLE_ACCOUNTS,ACCOUNTS_ID + "String_Node_Str" + accountId,null);
            if (userUnlocked) {
              db.delete(CE_TABLE_ACCOUNTS,ACCOUNTS_ID + "String_Node_Str" + accountId,null);
            }
            db.setTransactionSuccessful();
          }
  finally {
            db.endTransaction();
          }
          accountDeleted=true;
          logRecord(db,DebugDbHelper.ACTION_AUTHENTICATOR_REMOVE,TABLE_ACCOUNTS,accountId,accounts);
          final Account account=new Account(accountName,accountType);
          accounts.userDataCache.remove(account);
          accounts.authTokenCache.remove(account);
          accounts.accountTokenCaches.remove(account);
        }
 else {
          ArrayList<String> accountNames=accountNamesByType.get(accountType);
          if (accountNames == null) {
            accountNames=new ArrayList<String>();
            accountNamesByType.put(accountType,accountNames);
          }
          accountNames.add(accountName);
        }
      }
      for (      Map.Entry<String,ArrayList<String>> cur : accountNamesByType.entrySet()) {
        final String accountType=cur.getKey();
        final ArrayList<String> accountNames=cur.getValue();
        final Account[] accountsForType=new Account[accountNames.size()];
        for (int i=0; i < accountsForType.length; i++) {
          accountsForType[i]=new Account(accountNames.get(i),accountType);
        }
        accounts.accountCache.put(accountType,accountsForType);
      }
    }
  finally {
      cursor.close();
      if (accountDeleted) {
        sendAccountsChangedBroadcast(accounts.userId);
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * Validate internal set of accounts against installed authenticators for given user. Clear cached authenticators before validating when requested.
 */
private void validateAccountsInternal(UserAccounts accounts,boolean invalidateAuthenticatorCache){
  if (Log.isLoggable(TAG,Log.DEBUG)) {
    Log.d(TAG,"String_Node_Str" + accounts.userId + "String_Node_Str"+ accounts.openHelper.isCeDatabaseAttached()+ "String_Node_Str"+ mLocalUnlockedUsers.get(accounts.userId));
  }
  if (SystemProperties.getBoolean("String_Node_Str",false)) {
    return;
  }
  if (invalidateAuthenticatorCache) {
    mAuthenticatorCache.invalidateCache(accounts.userId);
  }
  final HashMap<String,Integer> knownAuth=getAuthenticatorTypeAndUIDForUser(mAuthenticatorCache,accounts.userId);
  boolean userUnlocked=isLocalUnlockedUser(accounts.userId);
synchronized (accounts.cacheLock) {
    final SQLiteDatabase db=accounts.openHelper.getWritableDatabase();
    boolean accountDeleted=false;
    Cursor metaCursor=db.query(TABLE_META,new String[]{META_KEY,META_VALUE},SELECTION_META_BY_AUTHENTICATOR_TYPE,new String[]{META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + "String_Node_Str"},null,null,META_KEY);
    HashSet<String> obsoleteAuthType=Sets.newHashSet();
    try {
      SparseBooleanArray knownUids=null;
      while (metaCursor.moveToNext()) {
        String type=TextUtils.split(metaCursor.getString(0),META_KEY_DELIMITER)[1];
        String uid=metaCursor.getString(1);
        if (TextUtils.isEmpty(type) || TextUtils.isEmpty(uid)) {
          Slog.e(TAG,"String_Node_Str" + TextUtils.isEmpty(type) + "String_Node_Str"+ TextUtils.isEmpty(uid));
          continue;
        }
        Integer knownUid=knownAuth.get(type);
        if (knownUid != null && uid.equals(knownUid.toString())) {
          knownAuth.remove(type);
        }
 else {
          if (knownUids == null) {
            knownUids=getUidsOfInstalledOrUpdatedPackagesAsUser(accounts.userId);
          }
          if (!knownUids.get(Integer.parseInt(uid))) {
            obsoleteAuthType.add(type);
            db.delete(TABLE_META,META_KEY + "String_Node_Str" + META_VALUE+ "String_Node_Str",new String[]{META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + type,uid});
          }
        }
      }
    }
  finally {
      metaCursor.close();
    }
    Iterator<Entry<String,Integer>> iterator=knownAuth.entrySet().iterator();
    while (iterator.hasNext()) {
      Entry<String,Integer> entry=iterator.next();
      ContentValues values=new ContentValues();
      values.put(META_KEY,META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + entry.getKey());
      values.put(META_VALUE,entry.getValue());
      db.insertWithOnConflict(TABLE_META,null,values,SQLiteDatabase.CONFLICT_REPLACE);
    }
    Cursor cursor=db.query(TABLE_ACCOUNTS,new String[]{ACCOUNTS_ID,ACCOUNTS_TYPE,ACCOUNTS_NAME},null,null,null,null,ACCOUNTS_ID);
    try {
      accounts.accountCache.clear();
      final HashMap<String,ArrayList<String>> accountNamesByType=new LinkedHashMap<>();
      while (cursor.moveToNext()) {
        final long accountId=cursor.getLong(0);
        final String accountType=cursor.getString(1);
        final String accountName=cursor.getString(2);
        if (obsoleteAuthType.contains(accountType)) {
          Slog.w(TAG,"String_Node_Str" + accountName + "String_Node_Str"+ accountType+ "String_Node_Str");
          db.beginTransaction();
          try {
            db.delete(TABLE_ACCOUNTS,ACCOUNTS_ID + "String_Node_Str" + accountId,null);
            if (userUnlocked) {
              db.delete(CE_TABLE_ACCOUNTS,ACCOUNTS_ID + "String_Node_Str" + accountId,null);
            }
            db.setTransactionSuccessful();
          }
  finally {
            db.endTransaction();
          }
          accountDeleted=true;
          logRecord(db,DebugDbHelper.ACTION_AUTHENTICATOR_REMOVE,TABLE_ACCOUNTS,accountId,accounts);
          final Account account=new Account(accountName,accountType);
          accounts.userDataCache.remove(account);
          accounts.authTokenCache.remove(account);
          accounts.accountTokenCaches.remove(account);
        }
 else {
          ArrayList<String> accountNames=accountNamesByType.get(accountType);
          if (accountNames == null) {
            accountNames=new ArrayList<String>();
            accountNamesByType.put(accountType,accountNames);
          }
          accountNames.add(accountName);
        }
      }
      for (      Map.Entry<String,ArrayList<String>> cur : accountNamesByType.entrySet()) {
        final String accountType=cur.getKey();
        final ArrayList<String> accountNames=cur.getValue();
        final Account[] accountsForType=new Account[accountNames.size()];
        for (int i=0; i < accountsForType.length; i++) {
          accountsForType[i]=new Account(accountNames.get(i),accountType);
        }
        accounts.accountCache.put(accountType,accountsForType);
      }
    }
  finally {
      cursor.close();
      if (accountDeleted) {
        sendAccountsChangedBroadcast(accounts.userId);
      }
    }
  }
}