Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-31028

invalid use of file objects in event triggers for plagiarism plugins.

    Details

    • Testing Instructions:
      Hide

      No core code uses these events or functions so testing options are limited. - it should be sufficient to check to make sure that uploading a file to an assignment occurs without any warnings. (old assignment upload/uploadsingle and new assign)

      Show
      No core code uses these events or functions so testing options are limited. - it should be sufficient to check to make sure that uploading a file to an assignment occurs without any warnings. (old assignment upload/uploadsingle and new assign)
    • Affected Branches:
      MOODLE_21_STABLE, MOODLE_22_STABLE
    • Fixed Branches:
      MOODLE_23_STABLE
    • Pull Master Branch:
      master-MDL-31028_2

      Description

      When an 'assessable_file_uploaded' event is to be processed in the Moodle cron job, depending on what operations have been performed earlier in the job, the 'stored_file' class may not yet be declared before the event data is unserialised. PHP will unserialise the objects but it substitutes an incomplete class type and the cron job will fail if any attempt is made to call methods of the file object contained in the event data.

      To demonstrate this, I have attached a simple local plugin (eventtest.tar.gz) that implements an event handler that defers an 'assessable_file_uploaded' event to be processed in the cron job. Create a course in a test instance, add a file upload assignment (single or advanced, it doesn't matter), and submit a file. Then, run the Moodle cron job from the CLI repeatedly. Some executions will succeed if other earlier operations have called get_file_storage() or required lib/filelib.php, but if the events queue processing is the first time those classes are needed, they won't exist before the event handler is called, by which time the event data has been unserialised in events_process_queued_handler() and is an incomplete class. (See example output below.)

      A simple solution for this specific problem is to add a hack in events_process_queued_handler() (patch attached) to pull in lib/filelib.php if the event being processed is 'assessable_file_uploaded', but the root of this issue is likely to come up for other classes if the same sort of circumstances happen there. Implementing autoloading may be one route around this, or avoid storing objects of any type but stdClass in event data.

      fowlerj@q08-0967 ~/src/moodle-org.git $ sudo -u www-data php admin/cli/cron.php 
      Server Time: Thu, 05 Jan 2012 11:55:53 +1000
       
       
      Running clean-up tasks...
       Deleted old cache_text records
       Executed tag cron
       Cleaned up context instances
       Built context paths
       Cleaned cache flags
       Cleaned up read notifications
      ...finished clean-up tasks
       Created missing context instances
      Cleaned up stale user sessions
      Running auth crons if required...
      Running enrol crons if required...
      Running cron for enrol_cohort...
      Starting activity modules
      Processing module function assignment_cron ...... used 2 dbqueries
      ... used 0.052798986434937 seconds
      done.
      Processing module function forum_cron ...Starting digest processing...
      Cleaned old digest records
      ... used 4 dbqueries
      ... used 0.048096179962158 seconds
      done.
      Finished activity modules
      Starting blocks
      Finished blocks
      Starting quiz reports
      Finished quiz reports
      Starting admin reports
      Finished admin reports
      Starting main gradebook job...
      done.
      Starting processing the event queue...
       *** in local_eventtest_handler::assessable_file_uploaded
       *** class_exists(stored_file) = true
       *** get_class($eventdata->files[e4a5b27283c568ae7e57014c3c2caf1b5c92d91e]) = stored_file
       *** get_class($eventdata->files[807b87cb6e01ead5107e37722a29ff9b26552363]) = stored_file
       *** get_class($eventdata->files[50afe513f4fef6e0d31952f79aec6b51e2ad7bb3]) = stored_file
      done.
      Starting course reports
      Finished course reports
      Starting gradebook plugins
      Finished gradebook plugins
      Fetching external blog entries...done.
      Deleting blog associations linked to non-existent contexts...done.
      Starting registration update on hubs...
      Finished registration update on hubs.
      Deleting session linked tokens more than one day old...done.
      Starting admin tools
      Processing cron function for tool_qeupgradehelper...
      done. (1 dbqueries, 0 seconds)
      Finished admin tools
      Processing customized cron scripts ...done.
      Checking automated backup status...INACTIVE
      Deleting old draft files... done.
      Cron script completed correctly
      Execution took 0.573476 seconds
       
       
       
      fowlerj@q08-0967 ~/src/moodle-org.git $ sudo -u www-data php admin/cli/cron.php 
      Server Time: Thu, 05 Jan 2012 11:55:55 +1000
       
       
       Created missing context instances
      Cleaned up stale user sessions
      Running auth crons if required...
      Running enrol crons if required...
      Starting activity modules
      Finished activity modules
      Starting blocks
      Finished blocks
      Starting quiz reports
      Finished quiz reports
      Starting admin reports
      Finished admin reports
      Starting main gradebook job...
      done.
      Starting processing the event queue...
       *** in local_eventtest_handler::assessable_file_uploaded
       *** class_exists(stored_file) = false
       *** get_class($eventdata->files[e4a5b27283c568ae7e57014c3c2caf1b5c92d91e]) = __PHP_Incomplete_Class
       *** get_class($eventdata->files[807b87cb6e01ead5107e37722a29ff9b26552363]) = __PHP_Incomplete_Class
       *** get_class($eventdata->files[50afe513f4fef6e0d31952f79aec6b51e2ad7bb3]) = __PHP_Incomplete_Class
      PHP Fatal error:  local_eventtest_handler::assessable_file_uploaded(): The script tried to execute a \
      method or access a property of an incomplete object. Please ensure that the class definition \
      "stored_file" of the object you are trying to operate on was loaded _before_ unserialize() gets \
      called or provide a __autoload() function to load the class definition \
        in /home/fowlerj/src/moodle-org.git/local/eventtest/lib.php on line 20
      PHP Stack trace:
      PHP   1. {main}() /home/fowlerj/src/moodle-org.git/admin/cli/cron.php:0
      PHP   2. cron_run() /home/fowlerj/src/moodle-org.git/admin/cli/cron.php:61
      PHP   3. events_cron() /home/fowlerj/src/moodle-org.git/lib/cronlib.php:342
      PHP   4. events_process_queued_handler() /home/fowlerj/src/moodle-org.git/lib/eventslib.php:448
      PHP   5. events_dispatch() /home/fowlerj/src/moodle-org.git/lib/eventslib.php:340
      PHP   6. call_user_func() /home/fowlerj/src/moodle-org.git/lib/eventslib.php:296
      PHP   7. local_eventtest_handler::assessable_file_uploaded() /home/fowlerj/src/moodle-org.git/lib/eventslib.php:0

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Votes:
                  1 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved:
                    Fix Release Date:
                    25/Jun/12