Problem/Motivation
This is somewhat tricky to reproduce, so the following STR are contrived. However I have seen this bug on D7 lead to a situation in which OpenID users were unable to log into their site, so it does have known real world effects.
Steps to reproduce:
- Add an image field to a user
- upload something to it
- Force-delete the image (from the command line, call file_delete($file, TRUE)) ... Note the user field is unchanged, but the file is gone from file_managed. for a real world example, presume that these file fields are moderated by admin, and some are deleted.
- Do a user_load and user_save
- Repeat the user_load and user_save (because the first time, the unique DB key is fine with the empty filename)
- Note error message about the unique key clash on filename "PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'uri': INSERT INTO {file_managed} (filesize, status, timestamp) [error] VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2)"
The issue is that the file field for the nonexistent file happily gets initialized with a default file object with an empty filename, but saving the user object attempts to create a new file from that default object that has no filename/uri. fild_field_presave only checks for !$file->status before saving it.
Proposed resolution
Alter file field handling behaviour so that either no default object is put into place if the file cannot be loaded, or add a further check on file_field_presave so that empty files don't get saved. Or don't allow files without a uri to be saved at all. Ideally the user object in this example does need to be updated though so that it no longer points to the nonexistent file.
Remaining tasks
- Track down more details of the path that causes the issue and improve proposed resolution
- Patch
- Review
User interface changes
None known
API changes
None known
Comments
Comment #1
aries commentedThe proposed solution could mess those systems which host the files on NFS, CDN or other not-100% reliable filesystem.
Comment #2
kenorb commentedSee: #1163740: PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 2: INSERT INTO {file_managed}
Comment #3
dave reidI believe this is a duplicate of #1677304: Remove drupal_deliver_page(), ajax_deliver(), drupal_deliver_html_page()
Comment #4
dave reidSorry I meant #1443158: file_field_presave assumes that a file object has been loaded