On Canon bodies and lens firmware 1.x, this lens identifies itself using
model number 150. Starting with firmware 2.x, this lens now identifies
itself using model number 368.
Exiv2 was correctly identifying the former but not the latter.
This commit also fixes a pre-existing bug in which exiv2 was not
correctly disambiguating lenses using model number 368.
0.9.1 remains broken regardless and is beyond fixing in this place.
Build-tested with both libssh 0.9.0 and 0.9.2.
Solution copied from KDE's kio-extras commit 24506c2af8d1904a99538543804306c6c2b81ca2
This PR (and fix981_canonAutoFocus2) use a decoder listed in TiffMappingInfo to
decode Exif.Canon.AFInfo. The decoding function "manufactures" Exif tags such as
Exif.Canon.AFNumPoints from the data in Exif.Canon.AFInfo. These tags must never
be written to file and are removed from the metadata in
exif.cpp/ExifParser::encode().
Three of the tags created (AFPointsInFocus,AFPointsSelected, AFPrimaryPoint) are
bitmasks. As the camera can have up to 64 focus points, the tags are a 64 bit
mask to say which points are active. The function printBitmask() reports data
such as 1,2,3 or (none).
This decoding function decodeCanonAFInfo() added to TiffMappingInfo manufactures
the new tags. Normally, tags are processed by the binary tag decoder and that
approach was taken in branch fix981_canonAf. However, the binary tag decoder
cannot deal with AFInfo because the size of some metadata arrays cannot be
determined at compile time.
This removes the AF from the name of the lens thus matching the name
that lensfun and exiftool determine.
(cherry picked from commit a573f9795baa1cf8a68296a80114fdc575f84319)
- Regression test for missing bounds check in MemIo::seek()
- Add bounds check to MemIo::seek(), this fixes CVE-2019-13504
(cherry picked from commit bd0afe0390439b2c424d881c8c6eb0c5624e31d9)
Additional fixes for 0.27:
- Add fix for the linux variant of MemIo::seek
- Change type of variable from unsigned to signed
Note that the problem occurs when data_size is less than header_size
what causes a buffer overflow in &data[i]
Co-Authored-By: D4N <dan.cermak@cgc-instruments.com>
* Fix 582 Add support for FocusPosition in Sony RAW files
* Thanks to @boardhead sonyFpCrypt() works correctly. Removed debug code. Fixed typos.
* Update doc/templates/Makefile to process Sony2Fp
* Following review by @boardhead. Renamed sonyFpCrypt() as sonyTagDecipher().
* Fixed writing the tag thanks to @boardhead explaining encipher/decipher.
Sadly, ArrayCfg/crpyt does not know if he's encrypting/decrypting.
I've added a sniff in TiffEncoder::visitBinaryArrayEnd to avoid changing the API.
* Added URL to discussion concerning sonyTagCipher()
* make sonyTagCipher() a static function with no external visibility.
* Add README-SAMPLES.md and remove exiv2samples.1
* Remove samples man page from CMake
* Add all sample programs to Doxygen.
* Adding links to source code on exiv2.org
Authored-By: Robin Mills <robin@clanmills.com>
Authored-By: Luis Díaz Más <piponazo@gmail.com>
This seems to have been caused by duplicate work between master branch
and 0.27-maintenance branch, as commit 3b48249eeb350301dfb3efa3ba6f7d7b162455be
had already got that right.
This function was printing the string from the array of strings nikonFocusArea,
but it wasn't verifying that the array index is actually valid.
Now this function will output "Invalid value" instead of crashing.
- Only export BasicError::setMsg which is the only implementation present in the .cpp
- Only export BasicError specialization on __APPLE__
It seems that gcc automatically adds the attribute when the visibility
settings are set to hidden. See this link for more information:
https://reviews.llvm.org/D35388
There is already a libxmp file by the xmp project on https://xmp.sf.net.
To avoid issues prefix with exiv2.
Fixes#624
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 89509d7a3915ba474cbc3f8c85ab9bec4954ceda)
Fix warnings when built with musl libc by using the correct path for
errno.h as defined in POSIX.
Fixes the following warning:
In file included from /home/ncopa/src/exiv2/src/http.cpp:74:
/usr/include/sys/errno.h:1:2: warning: #warning redirecting incorrect #include <sys/errno.h> to <errno.h> [-Wcpp]
#warning redirecting incorrect #include <sys/errno.h> to <errno.h>
^~~~~~~
Only GNU libc has implementation of the GNU variant of strerror_r, so
also for __GLIBC__ to determine which strerror_r implemenation to use.
This fixes build with musl libc, which makes some, but not all, GNU
extensions available with _GNU_SOURCE.
I have restored the Macro EXIV2_TEST_VERSION in include/exiv2/version.hpp
I have added an option --version-test to exifprint.cpp to test/validate EXIV2_TEST_VERSION works as documented.
Version strings in Exiv2 v0.27 and later have a fourth digit to indicate the pre-release number of the build.
Pre-release builds should never be used for production purposes.
Note that the getopt code was looping forever when one of the argument
options was incorrect. Example:
./exiv2 -A 20:00:00 -Y 2018 -O 11 -D 01 ad myImage.tiff
- reimplement binaryToString:
- it now accepts a Slice and nothing else
- it does not return a std::string but instead a proxy object that implements
operator<< (this should be more efficient, as we do not need to touch the
heap in most cases)
- addapt unit tests
- replace all occurences with the new API
binaryToString(DataBuf&) only calls the C-array version. Unfortunately, its
safety check is flawed, as it only works when start is 0 (probably due to its
conterintuitive interface).
binaryToString(byte*) formats the range (start,start+size) => we have to trimm
size if size + start is larger than the DataBuf's size_
On Linux we were merely checking whether f is finite, but that does
not cover the case f=NaN.
=> use isfinite instead which checks whether f != inf && f != NaN
This function extracts a 2, 4 or 8 byte integer from the image and
swaps it according to the current setting. However, it was implicitly
assuming, that it reads the same amount from the image is is
requested.
If that is not the case, e.g. if 8 bytes are requested but
only 4 are read
=> result is created via byteSwap8() which reads 8 bytes
!but 4 of those are uninitialized!
Using the actually read size fixes this problem.
While taking an EnVar as the parameter is more clear it has the
disadvantage, that passing anything outside of the range of the
enumeration is undefined behavior. The compiler could then optimize
the range check in getEnv away (perfectly legal due to UB), leading
to buffer overreads.
This function was creating a lot of new pointers and strings without
properly checking the array bounds. This commit adds several calls
to enforce(), making sure that the pointers stay within bounds.
Strings are now created using the helper function
string_from_unterminated() to prevent overreads in the constructor of
std::string.
This fixes#400
EXV_WARN_UNUSED_RESULT is a conditional macro that expands to either
__attribute__((warn_unused_result)) on gcc & clang or to _Check_return
for MSVC
=> Compiler warns if the return value is ignored
in the following call:
getHeaderOffset (payload.pData_, payload.size_, (byte*)&exifLongHeader, 6);
getHeaderOffset would read 6 bytes from exifLongHeader, reading beyond the
bounds of the array => add 2 padding bytes to prevent overreads
memcmp() compares the read data from key with the provided string, but when
key.pData_ is shorter than the provided length, then memcmp can read beyond the
bounds of key.pData_
=> add custom compare function, which ensures that we never read more than
key.size_
The pointer p is advanced in the while loop to step over three '\n'.
However, its length is never reduced accordingly. => the length check in the
following for loop is invalid, as it permits overreading by the number of
characters that p was advanced by.
The loop condition will perform a range check correctly, but it will always
dereference bytes[i], even if i is too large and fails the second check.
=> move the bytes[i] == 0x1c check into a if, after the range check was
successfull
DataBuf::release() easily cause memory leaks, when the return value is
ignored. free() provides the desired behavior, when the internal data should
just be deleted and not used further.
The size parameter is only checked for upper bounds, but not for lower.
If it is too small, then created dataBuf will be too small and overflow in one
of the subsequent memcpy() calls.
This fixes#378 / CVE-2018-14046
Several checks for extracted values performed no overflow checks on the
addition. They can be tricked into passing, albeit the individual summands are
too large.
=> use Safe::add() which now aborts when an overflow occurs
This fixes#366
offset_ can become arbitrarily large and overflows once its added to size_,
this causes all kinds of problems further in the code when offset_ is used
again.
=> Use Safe::add() to catch potential overflows
This fixes#365.
V803 Decreased performance. In case 'userEnd' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. futils.cpp 405
V803 Decreased performance. In case 'authEnd' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. futils.cpp 410
V803 Decreased performance. In case 'hostEnd' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. futils.cpp 428
V803 Decreased performance. In case 'e' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. epsimage.cpp 711
V803 Decreased performance. In case 'e' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. epsimage.cpp 841
V803 Decreased performance. In case 'e' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. epsimage.cpp 958
V803 Decreased performance. In case 'i' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. epsimage.cpp 855
V803 Decreased performance. In case 'it' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. jpgimage.cpp 817
V803 Decreased performance. In case 'lib' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. version.cpp 508
V803 Decreased performance. In case 'it' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. version.cpp 563
V803 Decreased performance. In case 'it' is iterator it's more effective to use prefix form of increment. Replace iterator++ with ++iterator. xmpsidecar.cpp 138
V762 It is possible a virtual function was overridden incorrectly. See third argument of function 'printStructure' in derived class 'TiffImage' and base class 'Image'. tiffimage.hpp 93
The warning was caused by -Wimplicit-fallthrough:
https://developers.redhat.com/blog/2017/03/10/wimplicit-fallthrough-in-gcc-7/
I also realized that the method printStructure was duplicated in the
classes Print and Erase. By moving the implementation to a free function
into the cpp file, I could remove the duplication in the code.
The xmp byte array is not necessarily null terminated => strstr can read beyond
the bounds of the allocated array then.
Therefore use string_from_unterminated to remedy this issue.
Also replace xmp with a std::vector, as stl functions can throw and we don't
want a memory leak.
signature is extracted from an image and can lack the terminating \0, this
causes the std::string constructor and strcmp to read beyond the bounds of the
allocated array.
=> Use string_from_unterminated to construct a std::string safely and use it
in the subsequent code & use stl functions instead of C functions
I introduced that file accidentally in the project while trying to move
the implementation details to xxx_int.cpp files. In this case, I found
out some issues and I just decided to leave the implementation in the
file tags.cpp.
This commit fixes the heap-buffer-overflow in PngChunk::parseTXTChunk.
According to the specification:
http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
There must be 2 null separators when we start to analyze the language tag.
Thanks to this upgrade the cmake code that handles the CURL dependency
can be simplified. Now we can use the shared version of CURL in all the
platforms. However we will use for the moment the static version on Mac,
since we are having some issues with 'make tests'. Once those tests are
migrated to python we can also use the shared version there.
In Params::evalGrep regcomp allocates some internal space for the regex objects,
which must be freed manually via regfree(). This was however only done when the
call to regcomp() failed and not on success. As the regexes are needed later,
they have to be deallocated by the destructor.
The compiler instrinsics are exposed via fully specialized template functions
which must not be defined twice (which they accidentally were). Declaring them
as inline fixes this issue.
- error was passed by value, but a new error message should be appended to it
=> error must be called by reference
- use default parameters of error() in http()
- rename variables to fix shadowing
- Define STRERROR_R_CHAR_P properly on CMake and use it on futils.cpp
- We use now _GNU_SOURCE to determine which version of strerror_r to use
- strError only throws if ret==ERANGE
- Remove STRERROR_R_CHAR_P. It has been never used
- sort defines in config.h.cmake
- Remove EXV_HAVE_DECL_STRERROR_R that is not used anymore
- Remove EXV_HAVE_STRERROR. C++98 always will have it
Pimpl class Impl is stored in raw pointers which are allocated on the heap in
the constructor. However, the constructor can throw an exception resulting in a
memory leak as the destructor is **not** invoked.
=> A smart pointer is however properly deallocated.
We also changed the way in which we copy the DLLs to the bin folder inside the build directory.
Before we were directly placing the conan-deps DLLs into the bin folder directly. Now we place
them into a directory called conanDlls, and from there we copy them to bin or install/bin
at build and install steps respectively.
CVE-2017-1000126 is a Stack out of bounds read in the WebP parser caused by the
parameter size & filesize being too large, causing the parser to land in an
infinite loop and eventually crash. Enforcing that the size over which the
parser iterates is smaller than the file fixes this issue.
This fixes#175.
The webp header contains the filesize of the image starting at the 8th byte in
bytes 4 to 8 encoded as a little endian 32 bit unsigned integer. The code was
erroneously assuming that the extracted filesize is starting at the 12th byte,
i.e. at the end of the WebP file header.
Source: https://developers.google.com/speed/webp/docs/riff_container
enforce is a function comparable to assert(), it ensures that a condition is
true. However, while assert() should be used for conditions where we can be
certain that they are true, enforce is intended to be used for conditions that
can fail (like on invalid input). Therefore enforce() throws an exception when
the condition is false and does not abort the program's execution. Also, it is
not turned off by defining NDEBUG.
- add a new file enforce.hpp
- implement enforce()
- templated structs were not required, SFINAE works for functions too
=> use instead, removes some unneeded code
- fix non-usage of builtins with clang
- adjust unit tests
The fallback signed integer overflow check is quite expensive, but the addition
can be safely performed when saved in an int due to integer promotion
rules. This makes the check a little less expensive.
- cdataBuf must be at least 8 bytes long otherwise decodeIHDRChunk
reads out of bounds
- pngImage::readMetadata now skips png chunks where the offset for
IHDR chunks is invalid
- added assertion into PngChunk::decodeIHDRChunk() to ensure dataBuf
size
When parsing a subBox that is a ColorHeader, a length is extracted
from the input file and fed directly into DataBuf() (which calls
malloc). A crafted input file can provide arbitrarily (up to
max(uint32_t)-8) large values and result in excessive memory
allocation.
This commit adds a check for the new size of DataBuf so that it is not
larger than the remaining size of the file.
This fixes#202 aka CVE-2018-4868
- consider that key is advanced by 8 bytes if stripHeader is true
=> length is reduced by same amount
Fixed by adding offset to the check in the loop
- Rewrote loop so that keysize is checked before the next
iteration (preventing an out of bounds read)
This change define explicitly the behavior that exiv2::getEnv should have
on response to unexpected inputs.
There are some other minor changes:
- Use _putenv_s for the unit tests on Windows
- Add todo comment
- Remove deprecated note about freeing memory
This commit adds a out-of-bounds protection in the case that the
extracted values for offset & count are summed up larger than the size
of the file. Also this function checks for overflows before performing
the addition.
This fixes#159
The invalid memory dereference in
Exiv2::getULong()/Exiv2::StringValueBase::read()/Exiv2::DataValue::read()
is caused further up the call-stack, by
v->read(pData, size, byteOrder) in TiffReader::readTiffEntry()
passing an invalid pData pointer (pData points outside of the Tiff
file). pData can be set out of bounds in the (size > 4) branch where
baseOffset() and offset are added to pData_ without checking whether
the result is still in the file. As offset comes from an untrusted
source, an attacker can craft an arbitrarily large offset into the
file.
This commit adds a check into the problematic branch, whether the
result of the addition would be out of bounds of the Tiff
file. Furthermore the whole operation is checked for possible
overflows.
A heap buffer overflow could occur in memcpy when icc.size_ is larger
than data.size_ - pad, as then memcpy would read out of bounds of data.
This commit adds a sanity check to iccLength (= icc.size_): if it is
larger than data.size_ - pad (i.e. an overflow would be caused) an
exception is thrown.
This fixes#71.
Source:
https://github.com/Exiv2/exiv2/issues/57#issuecomment-333086302
tc can be a null pointer when the TIFF tag is unknown (the factory
then returns an auto_ptr(0)) => as this can happen for corrupted
files, an explicit check should be used because an assertion can be
turned of in release mode (with NDEBUG defined)
This also fixes#57
At least the musl libc on Linux has the same issue as Mac OS X: the
PTHREAD_RECURSIVE_* static initialiser does not exist. This is a
documented and purposeful omission:
http://www.openwall.com/lists/musl/2017/02/20/3
This commit uses similar logic to the Apple test on other Unixes.
=> Should fix#76 (most of the work has been done by Robin Mills in
6e3855aed7)
The problem with #76 is the contents of the 26th IFD, with the
following contents:
tag: 0x8649
type: 0x1
count: 0xffff ffff
offset: 0x4974
The issue is the size of count (uint32_t), as adding anything to it
causes an overflow. Especially the expression:
(size*count + pad+20)
results in an overflow and gives 20 as a result instead of
0x100000014, thus the condition in the if in the next line is false
and the program continues to run (until it crashes at io.read).
To properly account for the overflow, the brackets have to be removed,
as then the result is saved in the correctly sized type and not cast
after being calculated in the smaller type.
The brackets have also been removed from bigtiffimage.cpp, where the
same issue is present.