Skip to:
Content

BuddyPress.org

Opened 7 weeks ago

Last modified 7 weeks ago

#9335 new defect (bug)

Crop fails when the uploaded image has "-bpfull" in the file name

Reported by: joneiseman's profile joneiseman Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 14.4.0
Component: Core Keywords:
Cc:

Description

I downloaded the existing avatar image and fixed the rotation. When I try to upload the file again to replace the existing image, the crop fails and I just get the message: There was a problem cropping your profile photo. This is due to a failure in the crop function in class-bp-attachmanet-avatar.php on line 311 because $data is null and that's because $absolute_path points to a non-existent file. The value of $absolute_path points to .../wp-content/uploads/avatars/2907/1763669118-bpfull-260x260.jpg

Attachments (1)

1763669118-bpfull.jpg (15.5 KB) - added by joneiseman 7 weeks ago.
When I try to upload this file as a profile image the cropping fails (due to the file name containg -bpfull in the name).

Download all attachments as: .zip

Change History (3)

#1 in reply to: ↑ description @joneiseman
7 weeks ago

The problem actually has nothing to do with the file size. It's failing because the name of the uploaded file contains -bpfull in the name and this results in the uploaded file getting removed when the crop function tries to cleanup the folder by calling the function bp_core_delete_existing_avatar

Replying to joneiseman:

I downloaded the existing avatar image and fixed the rotation. When I try to upload the file again to replace the existing image, the crop fails and I just get the message: There was a problem cropping your profile photo. This is due to a failure in the crop function in class-bp-attachmanet-avatar.php on line 311 because $data is null and that's because $absolute_path points to a non-existent file. The value of $absolute_path points to .../wp-content/uploads/avatars/2907/1763669118-bpfull-260x260.jpg

@joneiseman
7 weeks ago

When I try to upload this file as a profile image the cropping fails (due to the file name containg -bpfull in the name).

#2 @joneiseman
7 weeks ago

  • Summary changed from Crop fails when the image is 260x260 pixels to Crop fails when the uploaded image has "-bpfull" in the file name

Here are my suggested code changes to fhe file buddypress/bp-core/classes/class-bp-attachment-avatar.php to fix this problem:

231,233d230
<               $safe_copy = dirname( $absolute_path ) . '/safe_tmp.' . pathinfo( $absolute_path, PATHINFO_EXTENSION );
<               copy( $absolute_path, $safe_copy );
<
246d242
<                       @unlink( $safe_copy );
314c310
<               $data = @getimagesize( $safe_copy );
---
>               $data = @getimagesize( $absolute_path );
317c313
<               $args['original_file'] = $safe_copy;
---
>               $args['original_file'] = $absolute_path;
343d338
<               @unlink( $safe_copy );

Here's the new version of the function crop.php:

<?php
        public function crop( $args = array() ) {
                // Bail if the original file is missing.
                if ( empty( $args['original_file'] ) ) {
                        return false;
                }

                if ( ! bp_attachments_current_user_can( 'edit_avatar', $args ) ) {
                        return false;
                }

                if ( 'user' === $args['object'] ) {
                        $avatar_dir = 'avatars';
                } else {
                        $avatar_dir = sanitize_key( $args['object'] ) . '-avatars';
                }

                $args['item_id'] = (int) $args['item_id'];

                /**
                 * Original file is a relative path to the image
                 * eg: /avatars/1/avatar.jpg
                 */
                $relative_path = sprintf( '/%s/%s/%s', $avatar_dir, $args['item_id'], basename( $args['original_file'] ) );
                $absolute_path = $this->upload_path . $relative_path;

                // Bail if the avatar is not available.
                if ( ! file_exists( $absolute_path ) ) {
                        return false;
                }

                $safe_copy = dirname( $absolute_path ) . '/safe_tmp.' . pathinfo( $absolute_path, PATHINFO_EXTENSION );
                copy( $absolute_path, $safe_copy );

                if ( empty( $args['item_id'] ) ) {

                        /** This filter is documented in bp-core/bp-core-avatars.php */
                        $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', dirname( $absolute_path ), $args['item_id'], $args['object'], $args['avatar_dir'] );
                } else {

                        /** This filter is documented in bp-core/bp-core-avatars.php */
                        $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', $this->upload_path . '/' . $args['avatar_dir'] . '/' . $args['item_id'], $args['item_id'], $args['object'], $args['avatar_dir'] );
                }

                // Bail if the avatar folder is missing for this item_id.
                if ( ! file_exists( $avatar_folder_dir ) ) {
                        @unlink( $safe_copy );
                        return false;
                }

                // Get the existing avatar files for the object.
                $existing_avatar = bp_core_fetch_avatar(
                        array(
                                'object'  => $args['object'],
                                'item_id' => $args['item_id'],
                                'html'    => false,
                        )
                );

                /**
                 * Check that the new avatar doesn't have the same name as the
                 * old one before moving the previous one into history.
                 */
                if ( ! empty( $existing_avatar ) && $existing_avatar !== $this->url . $relative_path ) {
                        // Avatar history is disabled, simply delete the existing avatar files.
                        if ( bp_avatar_history_is_disabled() ) {
                                bp_core_delete_existing_avatar(
                                        array(
                                                'object'      => $args['object'],
                                                'item_id'     => $args['item_id'],
                                                'avatar_path' => $avatar_folder_dir,
                                        )
                                );
                        } else {
                                // Add a new revision for the existing avatar.
                                $avatars = bp_attachments_list_directory_files( $avatar_folder_dir );

                                if ( $avatars ) {
                                        foreach ( $avatars as $avatar_file ) {
                                                if ( ! isset( $avatar_file->name, $avatar_file->id, $avatar_file->path ) ) {
                                                        continue;
                                                }

                                                $is_full  = preg_match( '/-bpfull/', $avatar_file->name );
                                                $is_thumb = preg_match( '/-bpthumb/', $avatar_file->name );

                                                if ( $is_full || $is_thumb ) {
                                                        $revision = $this->add_revision(
                                                                'avatar',
                                                                array(
                                                                        'file_abspath' => $avatar_file->path,
                                                                        'file_id'      => $avatar_file->id,
                                                                )
                                                        );

                                                        if ( is_wp_error( $revision ) ) {
                                                                error_log( $revision->get_error_message() );
                                                        }
                                                }
                                        }
                                }
                        }
                }

                // Make sure we at least have minimal data for cropping.
                if ( empty( $args['crop_w'] ) ) {
                        $args['crop_w'] = bp_core_avatar_full_width();
                }

                if ( empty( $args['crop_h'] ) ) {
                        $args['crop_h'] = bp_core_avatar_full_height();
                }

                // Get the file extension.
                $data = @getimagesize( $safe_copy );
                $ext  = $data['mime'] === 'image/png' ? 'png' : 'jpg';

                $args['original_file'] = $safe_copy;
                $args['src_abs']       = false;

                $avatar_types = array(
                        'full'  => '',
                        'thumb' => '',
                );
                $timestamp    = bp_core_current_time( true, 'timestamp' );

                foreach ( $avatar_types as $key_type => $type ) {
                        if ( 'thumb' === $key_type ) {
                                $args['dst_w'] = bp_core_avatar_thumb_width();
                                $args['dst_h'] = bp_core_avatar_thumb_height();
                        } else {
                                $args['dst_w'] = bp_core_avatar_full_width();
                                $args['dst_h'] = bp_core_avatar_full_height();
                        }

                        $filename         = wp_unique_filename( $avatar_folder_dir, $timestamp . "-bp{$key_type}.{$ext}" );
                        $args['dst_file'] = $avatar_folder_dir . '/' . $filename;

                        $avatar_types[ $key_type ] = parent::crop( $args );
                }

                // Remove the original.
                @unlink( $absolute_path );
                @unlink( $safe_copy );

                // Return the full, thumb cropped avatars and the timestamp.
                return array_merge(
                        $avatar_types,
                        array(
                                'timestamp' => $timestamp,
                        )
                );
        }
Note: See TracTickets for help on using tickets.