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

Avoid integer divide by zero #1750

Merged
merged 3 commits into from
Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions include/exiv2/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1560,7 +1560,7 @@ namespace Exiv2 {
{
value_.clear();
long ts = TypeInfo::typeSize(typeId());
if (ts != 0)
if (ts > 0)
if (len % ts != 0) len = (len / ts) * ts;
for (long i = 0; i < len; i += ts) {
value_.push_back(getValue<T>(buf + i, byteOrder));
Expand Down Expand Up @@ -1644,15 +1644,15 @@ namespace Exiv2 {
template<>
inline long ValueType<Rational>::toLong(long n) const
{
ok_ = (value_.at(n).second != 0 && INT_MIN < value_.at(n).first && value_.at(n).first < INT_MAX );
ok_ = (value_.at(n).second > 0 && INT_MIN < value_.at(n).first && value_.at(n).first < INT_MAX );
if (!ok_) return 0;
return value_.at(n).first / value_.at(n).second;
}
// Specialization for unsigned rational
template<>
inline long ValueType<URational>::toLong(long n) const
{
ok_ = (value_.at(n).second != 0 && value_.at(n).first < LARGE_INT);
ok_ = (value_.at(n).second > 0 && value_.at(n).first < LARGE_INT);
if (!ok_) return 0;
return value_.at(n).first / value_.at(n).second;
}
Expand Down
16 changes: 10 additions & 6 deletions src/minoltamn_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2172,16 +2172,20 @@ namespace Exiv2 {

if ( model == "ILCE-6000" && maxAperture == F1_8 ) try {
long focalLength = getKeyLong ("Exif.Photo.FocalLength" ,metadata);
long focalL35mm = getKeyLong ("Exif.Photo.FocalLengthIn35mmFilm",metadata);
long focalRatio = (focalL35mm*100)/focalLength;
if ( inRange(focalRatio,145,155) ) index = 2 ;
if (focalLength > 0) {
long focalL35mm = getKeyLong ("Exif.Photo.FocalLengthIn35mmFilm",metadata);
long focalRatio = (focalL35mm*100)/focalLength;
if ( inRange(focalRatio,145,155) ) index = 2 ;
}
} catch (...) {}

if ( model == "ILCE-6000" && maxApertures.find(maxAperture) != maxApertures.end() ) try {
long focalLength = getKeyLong ("Exif.Photo.FocalLength" ,metadata);
long focalL35mm = getKeyLong ("Exif.Photo.FocalLengthIn35mmFilm",metadata);
long focalRatio = (focalL35mm*100)/focalLength;
if ( inRange(focalRatio,145,155) ) index = 3 ;
if (focalLength > 0) {
long focalL35mm = getKeyLong ("Exif.Photo.FocalLengthIn35mmFilm",metadata);
long focalRatio = (focalL35mm*100)/focalLength;
if ( inRange(focalRatio,145,155) ) index = 3 ;
}
} catch (...) {}

if ( index > 0 ) {
Expand Down
2 changes: 1 addition & 1 deletion src/tags_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2601,7 +2601,7 @@ namespace Exiv2 {
std::ostream& printLong(std::ostream& os, const Value& value, const ExifData*)
{
Rational r = value.toRational();
if (r.second != 0) return os << static_cast<long>(r.first) / r.second;
if (r.second > 0) return os << static_cast<long>(r.first) / r.second;
return os << "(" << value << ")";
} // printLong

Expand Down
Binary file added test/data/issue_ghsa_pvjp_m4f6_q984_poc.exv
Binary file not shown.
36 changes: 36 additions & 0 deletions tests/bugfixes/github/test_issue_ghsa_pvjp_m4f6_q984.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-

from system_tests import CaseMeta, path


class MinoltaDivZero(metaclass=CaseMeta):
"""
Regression test for the bug described in:
https://github.com/Exiv2/exiv2/security/advisories/GHSA-pvjp-m4f6-q984
"""
url = "https://github.com/Exiv2/exiv2/security/advisories/GHSA-pvjp-m4f6-q984"

filename = path("$data_path/issue_ghsa_pvjp_m4f6_q984_poc.exv")
commands = ["$exiv2 -p t $filename"]
stderr = ["""Error: Upper boundary of data for directory Image, entry 0x011a is out of bounds: Offset = 0x000000f2, size = 14155784, exceeds buffer size by 14110766 Bytes; truncating the entry
Error: Offset of directory Photo, entry 0x829a is out of bounds: Offset = 0x6d00035e; truncating the entry
Error: Upper boundary of data for directory Photo, entry 0x8822 is out of bounds: Offset = 0x00000003, size = 56834, exceeds buffer size by 11577 Bytes; truncating the entry
Error: Upper boundary of data for directory Photo, entry 0x8827 is out of bounds: Offset = 0x00000640, size = 1179650, exceeds buffer size by 1135990 Bytes; truncating the entry
Warning: Directory Photo, entry 0x8832 has unknown Exif (TIFF) type 49; setting type size 1.
Error: Offset of directory Sony2, entry 0x2006 is out of bounds: Offset = 0x00000000; truncating the entry
Warning: Directory Sony2, entry 0x20c1 has unknown Exif (TIFF) type 181; setting type size 1.
Error: Offset of directory Sony2, entry 0x2063 is out of bounds: Offset = 0x00000000; truncating the entry
Error: Offset of directory Sony2, entry 0x3000 is out of bounds: Offset = 0x0057097c; truncating the entry
Error: Offset of directory Sony2, entry 0x0115 is out of bounds: Offset = 0x00000000; truncating the entry
Error: Upper boundary of data for directory Sony2, entry 0x2013 is out of bounds: Offset = 0x00000002, size = 37486596, exceeds buffer size by 37441338 Bytes; truncating the entry
Warning: Directory Photo, entry 0xa003 has unknown Exif (TIFF) type 242; setting type size 1.
Warning: Directory Iop has an unexpected next pointer; ignored.
Warning: Directory Photo, entry 0xa402 has unknown Exif (TIFF) type 89; setting type size 1.
Error: Offset of directory Photo, entry 0xa402 is out of bounds: Offset = 0x00000000; truncating the entry
Error: Offset of directory Thumbnail, entry 0x0132 is out of bounds: Offset = 0xff00968b; truncating the entry
"""]
retval = [0]

def compare_stdout(self, i, command, got_stdout, expected_stdout):
""" We don't care about the stdout, just don't crash """
pass