Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust stream chunk size to load big exif metadata #40600

Merged
merged 5 commits into from
Feb 8, 2023

Conversation

jvillafanez
Copy link
Member

Description

There were problems loading the exif metadata of some images if the metadata was too large. This was causing problems loading the images because the right orientation was in the metadata that wasn't loaded.

Related Issue

https://github.com/owncloud/enterprise/issues/5500

Motivation and Context

Users expect the image to be loaded with the right orientation, like most of the apps.

How Has This Been Tested?

Just upload the image below:
portrait

Tested with and without encryption. I'm not aware of any additional stream wrapper that could affect the behavior (quota isn't applied to read streams)

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Database schema changes (next release will require increase of minor version instead of patch)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Technical debt
  • Tests only (no source changes)

Checklist:

  • Code changes
  • Unit tests added
  • Acceptance tests added
  • Documentation ticket raised:
  • Changelog item, see TEMPLATE

Supersedes #40586

@jvillafanez jvillafanez force-pushed the load_big_exif_metadata branch from 441f1f5 to c7bea82 Compare January 24, 2023 10:53
Copy link
Contributor

@phil-davis phil-davis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changelog needed

@owncloud owncloud deleted a comment from update-docs bot Jan 25, 2023
Copy link
Contributor

@phil-davis phil-davis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable to me. Needs a dev to review.

Copy link
Member

@DeepDiver1975 DeepDiver1975 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My usual question: unit test? 🙈

$stream = $handle;
$metadata = \stream_get_meta_data($stream);
while ($metadata['stream_type'] === 'user-space') {
\stream_set_chunk_size($stream, 64 * 1024);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error handling?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok - not really - it only fails if the chunk size is negative or bigger then php max int ....https://www.php.net/manual/en/function.stream-set-chunk-size.php

@jvillafanez
Copy link
Member Author

I don't think unit tests are possible in the strict sense. We need a custom stream wrapper to trigger the behavior, so we either create a custom wrapper just for the tests or use ownCloud's node or view object to get the stream.

Even if we include integration tests as unit tests, it will take some time (estimate ~2 days) and it's unlikely to cover all the cases (need to find TIFF images that trigger this behavior).

@mrow4a
Copy link
Contributor

mrow4a commented Jan 26, 2023

I don't think unit tests are possible in the strict sense. We need a custom stream wrapper to trigger the behavior, so we either create a custom wrapper just for the tests or use ownCloud's node or view object to get the stream.

Even if we include integration tests as unit tests, it will take some time (estimate ~2 days) and it's unlikely to cover all the cases (need to find TIFF images that trigger this behavior).

I think it would be good to cover it with some integration/unit/acceptance test, or hybrid of it. Same story as with https://github.com/owncloud/files_classifier/tree/master/tests/acceptance/data and https://github.com/owncloud/files_classifier/blob/master/tests/unit/DocumentPropertiesTest.php#L37-L67

@pako81
Copy link

pako81 commented Jan 30, 2023

@jvillafanez @mrow4a do we want to have tests for this one?

@jvillafanez
Copy link
Member Author

If it's required, I'd vote for open a tech debt ticket to include the tests because it will take time. Note that, as said, we'd need to create a custom wrapper to trigger the behavior.

@jvillafanez jvillafanez force-pushed the load_big_exif_metadata branch from e6b4179 to 5fc0e62 Compare February 2, 2023 11:27
@jvillafanez
Copy link
Member Author

I've added a test that should cover the main use case, but there are things still not covered:

  • TIFF images aren't loaded with the gd extension. This means that the code will be left untested for .tiff files. Currently, the exif data is loaded only if the image is loaded, so we'd need to change the code to load the exif data regardless of the images, but the data is pointless if we can't load the image.
  • We're using the close stream wrapper because it seems the easiest one we can reuse. However, this will trigger a warning due to the missing getSource method. This is still ok for the tests because there isn't any additional custom wrapper in the stream whose chunk size needs to be adjusted. It shouldn't cause problems.

@jvillafanez jvillafanez force-pushed the load_big_exif_metadata branch from 5fc0e62 to a945880 Compare February 2, 2023 11:35
@jvillafanez
Copy link
Member Author

@DeepDiver1975 is this good enough?


$img->loadFromFileHandle($stream);
\fclose($stream);
$this->assertSame(6, $img->getOrientation()); // orientation = right, top
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all assert functions of phpunit are static if I am not totally miss taken ....

Should be self::assertSame ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$this->assertSomething() is done throughout the existing code.
But yes, the asserts are like:

    public static function assertSame($expected, $actual, string $message = ''): void

I wonder why we have done $this-> rather than self:: for all these years?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe because earlier versions of phpunit have been using this-> ... no idea ..

I tend to fix such things when touching any code base ..... my idea is even throwing this as warnings into my face 🤷

@ownclouders
Copy link
Contributor

ownclouders commented Feb 8, 2023

💥 Acceptance tests pipeline apiWebdavDelete-mariadb10.2-php7.4 failed. The build has been cancelled.

https://drone.owncloud.com/owncloud/core/37892/75

@ownclouders
Copy link
Contributor

💥 Acceptance tests pipeline apiProvisioningGroups-v1-mariadb10.2-php7.4 failed. The build has been cancelled.

https://drone.owncloud.com/owncloud/core/37892/44

@phil-davis
Copy link
Contributor

I restarted CI - some pipelines failed when initially fetching docker images.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 8, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 5 Code Smells

65.2% 65.2% Coverage
0.0% 0.0% Duplication

@DeepDiver1975 DeepDiver1975 merged commit 84db34d into master Feb 8, 2023
@delete-merged-branch delete-merged-branch bot deleted the load_big_exif_metadata branch February 8, 2023 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants