wiki.techinc.nl/tests/phpunit/includes/media/JpegMetadataExtractorTest.php
Derk-Jan Hartman 9ce26a564d Fix XMP parser errors due to trailing nullchar
JPEG files can have trailing \0 chars at the end of the XMP value. Use
trim() to remove these from the string value.

Bug: T118799
Change-Id: Id4ab223ef432e5d2c0dd3b4e332320db02422700
2019-09-11 22:34:33 +00:00

134 lines
5 KiB
PHP

<?php
/**
* @todo Could use a test of extended XMP segments. Hard to find programs that
* create example files, and creating my own in vim probably wouldn't
* serve as a very good "test". (Adobe photoshop probably creates such files
* but it costs money). The implementation of it currently in MediaWiki is based
* solely on reading the standard, without any real world test files.
*
* @group Media
* @covers JpegMetadataExtractor
*/
class JpegMetadataExtractorTest extends MediaWikiIntegrationTestCase {
protected $filePath;
protected function setUp() {
parent::setUp();
$this->filePath = __DIR__ . '/../../data/media/';
}
/**
* We also use this test to test padding bytes don't
* screw stuff up
*
* @param string $file Filename
*
* @dataProvider provideUtf8Comment
*/
public function testUtf8Comment( $file ) {
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . $file );
$this->assertEquals( [ 'UTF-8 JPEG Comment — ¼' ], $res['COM'] );
}
public static function provideUtf8Comment() {
return [
[ 'jpeg-comment-utf.jpg' ],
[ 'jpeg-padding-even.jpg' ],
[ 'jpeg-padding-odd.jpg' ],
];
}
/** The file is iso-8859-1, but it should get auto converted */
public function testIso88591Comment() {
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-iso8859-1.jpg' );
$this->assertEquals( [ 'ISO-8859-1 JPEG Comment - ¼' ], $res['COM'] );
}
/** Comment values that are non-textual (random binary junk) should not be shown.
* The example test file has a comment with a 0x5 byte in it which is a control character
* and considered binary junk for our purposes.
*/
public function testBinaryCommentStripped() {
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-binary.jpg' );
$this->assertEmpty( $res['COM'] );
}
/* Very rarely a file can have multiple comments.
* Order of comments is based on order inside the file.
*/
public function testMultipleComment() {
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-multiple.jpg' );
$this->assertEquals( [ 'foo', 'bar' ], $res['COM'] );
}
public function testXMPExtraction() {
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' );
$expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' );
$this->assertEquals( $expected, $res['XMP'] );
}
public function testPSIRExtraction() {
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' );
$expected = '50686f746f73686f7020332e30003842494d04040000000'
. '000181c02190004746573741c02190003666f6f1c020000020004';
$this->assertEquals( $expected, bin2hex( $res['PSIR'][0] ) );
}
public function testXMPExtractionNullChar() {
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-nullchar.jpg' );
$expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' );
$this->assertEquals( $expected, $res['XMP'] );
}
public function testXMPExtractionAltAppId() {
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-alt.jpg' );
$expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' );
$this->assertEquals( $expected, $res['XMP'] );
}
public function testIPTCHashComparisionNoHash() {
$segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' );
$res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] );
$this->assertEquals( 'iptc-no-hash', $res );
}
public function testIPTCHashComparisionBadHash() {
$segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-bad-hash.jpg' );
$res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] );
$this->assertEquals( 'iptc-bad-hash', $res );
}
public function testIPTCHashComparisionGoodHash() {
$segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-good-hash.jpg' );
$res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] );
$this->assertEquals( 'iptc-good-hash', $res );
}
public function testExifByteOrder() {
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'exif-user-comment.jpg' );
$expected = 'BE';
$this->assertEquals( $expected, $res['byteOrder'] );
}
public function testInfiniteRead() {
// test file truncated right after a segment, which previously
// caused an infinite loop looking for the next segment byte.
// Should get past infinite loop and throw in wfUnpack()
$this->setExpectedException( 'MWException' );
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-segment-loop1.jpg' );
}
public function testInfiniteRead2() {
// test file truncated after a segment's marker and size, which
// would cause a seek past end of file. Seek past end of file
// doesn't actually fail, but prevents further reading and was
// devolving into the previous case (testInfiniteRead).
$this->setExpectedException( 'MWException' );
$res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-segment-loop2.jpg' );
}
}