Uploaded image for project: 'CiviCRM'
  1. CiviCRM
  2. CRM-13287

Memory exhaustion in CRM_Core_BAO_UFGroup and the Legend of Paal Paysam

    Details

    • Documentation Required?:
      None
    • Funding Source:
      Needs Funding

      Description

      A fatal PHP 'Out of Memory' error is generated on validating a membership form with many custom fields embedded. This happened in cases where there are around 30 custom fields on the form. The error is generated on the 3rd screen just after the membership is generated in the DB and when the email receipt is prepared to be sent.

      After investigation, the error comes from this code block in CRM_Core_BAO_UFGroup::getValues():
      $nullIndex = $nullValueIndex = ' ';
      [...]
      $index = $field['title'];
      //handle for the label not set for the field
      if (empty($field['title']))

      { $index = $nullIndex; $nullIndex .= $nullIndex; }

      //handle the case to avoid re-write where the profile field labels are the same
      if (CRM_Utils_Array::value($index, $values))

      { $index .= $nullValueIndex; $nullValueIndex .= $nullValueIndex; }

      The purpose is apparently to come out with a unique key when the field title title is not set or when the field already exists elsewhere. However the method chosen reminds of the Legend of Paal Paysam:

      The legend goes that the tradition of serving Paal Paysam to visiting pilgrims started after a game of chess between the local king and the lord Krishna himself. The king was a big chess enthusiast and had the habit of challenging wise visitors to a game of chess. One day a traveling sage was challenged by the king. To motivate his opponent the king offered any reward that the sage could name. The sage modestly asked just for a few grains of rice in the following manner: the king was to put a single grain of rice on the first chess square and double it on every consequent one.
      You know the rest of the story (if not read: http://www.singularitysymposium.com/exponential-growth.html).

      So in the above code snippet, by the 30th custom field that goes in this loop the $nullValueIndex is a 1Gb string of spaces! No wonder we have the memory exhaustion errors!

      I would recommend:

      • at the very least to replace these statements with:
        $nullIndex .= ' ';
        [...]
        $nullValueIndex .= ' ';
      • but most certainly to move to numeric counters:
        $nullIndex = $nullValueIndex = 1;
        [...]
        $index = $nullIndex++;
        [...]
        $index .= $nullValueIndex++;

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              nganivet Nicolas Ganivet
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - 30 minutes
                30m
                Remaining:
                Remaining Estimate - 30 minutes
                30m
                Logged:
                Time Spent - Not Specified
                Not Specified