Hi,

I found a bug - H323Capabilities::Remove function will skip item when doing .RemoveAt operation. In result I have had a crash (in line if (set[outer][middle][inner].GetCapabilityNumber() == capabilityNumber)) for some sets of capabilities.
I can't understand why the crash is occurs but in any way...


Original code:

void H323Capabilities::Remove(H323Capability * capability)
{
  if (capability == NULL)
    return;

  PTRACE(3, "H323\tRemoving capability: " << *capability);

  unsigned capabilityNumber = capability->GetCapabilityNumber();

  for (PINDEX outer = 0; outer < set.GetSize(); outer++) {
    for (PINDEX middle = 0; middle < set[outer].GetSize(); middle++) {
      for (PINDEX inner = 0; inner < set[outer][middle].GetSize(); inner++) {
        if (set[outer][middle][inner].GetCapabilityNumber() == capabilityNumber) {
          set[outer][middle].RemoveAt(inner);
          break;
        }
      }
      if (set[outer][middle].GetSize() == 0)
        set[outer].RemoveAt(middle);

    }
    if (set[outer].GetSize() == 0)
        set.RemoveAt(outer);
  }


My fix:

void H323Capabilities::Remove(H323Capability * capability)
{
  if (capability == NULL)
    return;

  PTRACE(3, "H323\tRemoving capability: " << *capability);

  unsigned capabilityNumber = capability->GetCapabilityNumber();

  for (PINDEX outer = 0; outer < set.GetSize(); ) {
    for (PINDEX middle = 0; middle < set[outer].GetSize(); ) {
      for (PINDEX inner = 0; inner < set[outer][middle].GetSize(); inner++) {
        if (set[outer][middle][inner].GetCapabilityNumber() == capabilityNumber) {
          set[outer][middle].RemoveAt(inner);
          break;
        }
      }
      if (set[outer][middle].GetSize())
        ++middle;
      else
        set[outer].RemoveAt(middle);

    }
    if (set[outer].GetSize())
        ++outer;
    else
        set.RemoveAt(outer);
  }

Thanks
--
Iurii Gordiienko