--- metacam-1.2.orig/Makefile
+++ metacam-1.2/Makefile
@@ -30,7 +30,7 @@ OSCXXFLAGS=-ansi -pedantic
 CXX=g++
 INCLUDES=
 
-CXXFLAGS=-Wall $(OSCXXFLAGS) -D_GNU_SOURCE -O2 $(INCLUDES)
+CXXFLAGS+=-Wall $(OSCXXFLAGS) -D_GNU_SOURCE -O2 $(INCLUDES)
 
 LIBOBJS=rationals.o exiftags.o \
      nikontags.o olympustags.o canontags.o casiotags.o dpyfuncs.o \
@@ -65,7 +65,7 @@ libmetacam.a:	$(LIBOBJS)
 	mv -f libmetacam.a- libmetacam.a
 
 metacam:	$(EXEOBJS) libmetacam.a
-	$(CXX) $(CXXFLAGS) $(EXEOBJS) -o metacam -lm -L. -lmetacam
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(EXEOBJS) -o metacam -lm -L. -lmetacam
 
 # Dependency rules
 dependencies:	Makefile $(DEPS)
--- metacam-1.2.orig/datatiff.h
+++ metacam-1.2/datatiff.h
@@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suit
 #define DATATIFF_H_INCLUDED
 
 #include "metatiff.h"
+#include <cstdlib>
 
 class _DataIFD;
 class _DataIFDEntry;
--- metacam-1.2.orig/edittiff.h
+++ metacam-1.2/edittiff.h
@@ -1,3 +1,4 @@
+
 /*
 ------------------------------------------------------------------------------
 MetaCam - Extract EXIF information from digital camera files, with
@@ -24,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suit
 #define EDITTIFF_H_INCLUDED
 
 #include "metatiff.h"
+#include <cstdlib>
 
 class _EditIFD;
 
--- metacam-1.2.orig/metacam.cc
+++ metacam-1.2/metacam.cc
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suit
 #include <iostream>
 #include <fstream>
 #include <cstdio>
+#include <cstdlib>
 #include <errno.h>
 #include <netinet/in.h>
 #include <string.h>
--- metacam-1.2.orig/ocontext.cc
+++ metacam-1.2/ocontext.cc
@@ -25,6 +25,8 @@ static const char *rcsid __attribute__((
 #include "odrivers.h"
 
 #include <ctype.h>
+#include <cstdlib>
+#include <cstring>
 
 OutputContext::~OutputContext()
 {
--- metacam-1.2.orig/dpyfuncs.cc
+++ metacam-1.2/dpyfuncs.cc
@@ -28,6 +28,8 @@ Foundation, Inc., 59 Temple Place - Suit
 #include "metacam.h"
 #include "dpyfuncs.h"
 
+#include <cstring>
+
 static const char *rcsid __attribute__((unused))="$Id: dpyfuncs.cc,v 1.14 2004/08/21 17:54:20 daniel Exp $";
 
 void
--- metacam-1.2.orig/dpyfuncs.cc
+++ metacam-1.2/dpyfuncs.cc
@@ -428,7 +428,7 @@ dpyCanonBlock1(OutputContext &ctx, const
 	}
 
 	if (v[4]) {
-	    static char *flashmodes[] = {
+	    static char const *flashmodes[] = {
 		"Auto", "On", "Red-Eye Reduction", "Slow Synchro",
 		"Auto + Red-Eye Reduction", "On + Red-Eye Reduction"
 	    };
@@ -444,7 +444,7 @@ dpyCanonBlock1(OutputContext &ctx, const
 	if (n >= 32 && v[32]) {
 	    fmt(ctx, "Focus Mode", "Continuous");
 	} else if (v[7] <= 6) {
-	    static char *focusModes[] = {
+	    static const char *focusModes[] = {
 		"One-Shot", "AI Servo", "AI Focus", "Manual Focus", 
 		"Single Focus", "Continuous Focus", "Manual Focus"
 	    };
@@ -452,14 +452,14 @@ dpyCanonBlock1(OutputContext &ctx, const
 	}
 
 	if (v[10] <= 2)	{
-	    static char *imageSizes[] = {
+	    static const char *imageSizes[] = {
 		"Large", "Medium", "Small"
 	    };
 	    fmt(ctx, "Image Size", imageSizes[v[10]]);
 	}
 
 	{
-	    static char *adjustment[] = { "Low", "Normal", "High", "unknown" };
+	    static const char *adjustment[] = { "Low", "Normal", "High", "unknown" };
 
 	   fmt(ctx, "Contrast", adjustment[((short)v[13] + 1) & 0x3]);
 	   fmt(ctx, "Saturation", adjustment[((short)v[14] + 1) & 0x3]);
@@ -467,34 +467,34 @@ dpyCanonBlock1(OutputContext &ctx, const
 	}
 
 	if (v[16] >= 15 && v[16] <= 19) {
-	    static char *speeds[] = { "auto", "50", "100", "200", "400" };
+	    static const char *speeds[] = { "auto", "50", "100", "200", "400" };
 
 	   fmt(ctx, "ISO Speed", speeds[v[16] - 15]);
 	}
 
 	if (v[17] >= 3 && v[17] <= 5) {
-	    static char *meterModes[] = {
+	    static const char *meterModes[] = {
 		"Evaluative", "Partial", "Center-weighted"
 	    };
 	   fmt(ctx, "Metering Mode", meterModes[v[17] - 3]);
 	}
 
 	if (v[18] >= 0x3000 && v[18] <= 0x3004) {
-	    static char *afPoints[] = {
+	    static const char *afPoints[] = {
 		"Manual Focus", "Auto-Select", "Right", "Center", "Left"
 	    };
 	   fmt(ctx, "Autofocus Point", afPoints[v[18] - 0x3000]);
 	}
 
 	if (v[20] <= 5) {
-	    static char *exposureModes[] = {
+	    static const char *exposureModes[] = {
 		"Preprogrammed", "Program", "Tv-priority", "Av-priority",
 		"Manual", "A-DEP"
 	    };
 	   fmt(ctx, "Exposure Mode", exposureModes[v[20]]);
 	}
 	if (v[20] == 0 && v[11] <= 11) {
-	    static char *shootModes[] = {
+	    static const char *shootModes[] = {
 		"Full Auto", "Manual", "Landscape", "Fast Shutter", "Slow Shutter",
 		"Night", "B&W", "Sepia", "Portrait", "Sports", "Macro / Close-Up",
 		"Pan Focus"
@@ -547,7 +547,7 @@ extern void dpyCanonBlock4(OutputContext
 //	int n = v[0] / 2;
 
 	if (v[7] <= 6) {
-	    static char *whiteBalances[] = {
+	    static const char *whiteBalances[] = {
 		"Auto", "Sunny", "Cloudy", "Tungsten", "Fluorescent", "Flash", "Custom"
 	    };
 	   fmt(ctx, "White Balance", whiteBalances[v[7]]);
@@ -561,7 +561,7 @@ extern void dpyCanonBlock4(OutputContext
 	}
 
 	{
-	    struct { unsigned short value; char *bias; } flashBias[] = {
+	    struct { unsigned short value; char const *bias; } flashBias[] = {
 		{0xffc0, "-2 EV"}, {0xffcc, "-1.67 EV"}, {0xffd0, "-1.50 EV"},
 		{0xffd4, "-1.33 EV"}, {0xffe0, "-1 EV"}, {0xffec, "-0.67 EV"},
 		{0xfff0, "-0.50 EV"}, {0xfff4, "-0.33 EV"}, {0x0000, "0 EV"},
--- metacam-1.2.orig/filetiff.cc
+++ metacam-1.2/filetiff.cc
@@ -72,7 +72,7 @@ size_t
 _FileTIFF::getData(unsigned char *buf, size_t bytes)
 {
     is.read((char*)buf, bytes);
-    if (is.gcount() != bytes) {
+    if ((unsigned)is.gcount() != bytes) {
 //	int err = errno;
 //	cerr << "Read failed: " << strerror(err) << endl;
 //	exit(2);
--- a/Makefile
+++ b/Makefile
@@ -30,7 +30,8 @@ OSCXXFLAGS=-ansi -pedantic
 CXX=g++
 INCLUDES=
 
-CXXFLAGS+=-Wall $(OSCXXFLAGS) -D_GNU_SOURCE -O2 $(INCLUDES)
+CXXFLAGS?=-O2
+CXXFLAGS+=-Wall $(OSCXXFLAGS) -D_GNU_SOURCE $(INCLUDES)
 
 LIBOBJS=rationals.o exiftags.o \
      nikontags.o olympustags.o canontags.o casiotags.o dpyfuncs.o \
@@ -65,7 +66,7 @@ libmetacam.a:	$(LIBOBJS)
 	mv -f libmetacam.a- libmetacam.a
 
 metacam:	$(EXEOBJS) libmetacam.a
-	$(CXX) $(CXXFLAGS) $(LDFLAGS) $(EXEOBJS) -o metacam -lm -L. -lmetacam
+	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(EXEOBJS) -o metacam -lm -L. -lmetacam
 
 # Dependency rules
 dependencies:	Makefile $(DEPS)
Description: Fix crashes on ill-formed Jpeg images.
             The patch adds vector size checking before
             accessing its elements.
--- a/dpyfuncs.cc
+++ b/dpyfuncs.cc
@@ -36,6 +36,7 @@ void
 dpyISO(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.size() < 2) return;
     ctx.startBlock(name) << v[1] << " (" << v[0] << ")";
     ctx.endBlock();
 }
@@ -44,6 +45,7 @@ void
 dpyString(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<string> v = e.getSTRING();
+    if (v.empty()) return;
     ctx.startBlock(name) << v[0];
     ctx.endBlock();
 }
@@ -74,6 +76,7 @@ void
 dpyLens(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffRATIONAL> v = e.getRATIONAL();
+    if (v.size() < 4) return;
     v[0] = v[0].normalize();
     v[1] = v[1].normalize();
     v[2] = v[2].normalize();
@@ -105,6 +108,7 @@ void
 dpyZoom(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffRATIONAL> v = e.getRATIONAL();
+    if (v.empty()) return;
     v[0] = v[0].normalize();
 
     ctx.startBlock(name);
@@ -123,6 +127,7 @@ void
 dpyExpAdjust(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffSRATIONAL> v = e.getSRATIONAL();
+    if (v.empty()) return;
     v[0] = v[0].normalize();
 
     ctx.startBlock(name);
@@ -139,6 +144,7 @@ void
 dpyShutter(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffRATIONAL> v = e.getRATIONAL();
+    if (v.empty()) return;
     v[0]=v[0].normalize();
  
     ctx.startBlock(name);
@@ -151,6 +157,7 @@ void
 dpyAperture(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffRATIONAL> v = e.getRATIONAL();
+    if (v.empty()) return;
 
     ctx.startBlock(name) << "f" << (double)v[0];
     ctx.endBlock();
@@ -160,6 +167,7 @@ void
 dpyPixels(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.empty()) return;
 
     ctx.startBlock(name) << v[0] << " pixels";
     ctx.endBlock();
@@ -169,6 +177,7 @@ void
 dpySigned(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffSIGNED> v = e.getSVALUE();
+    if (v.empty()) return;
 
     ctx.startBlock(name);
     if (v[0] > 0) {
@@ -183,6 +192,7 @@ void
 dpyUnsigned(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.empty()) return;
     ctx.startBlock(name) << v[0];
     ctx.endBlock();
 }
@@ -191,6 +201,7 @@ void
 dpyResolution(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffRATIONAL> v = e.getRATIONAL();
+    if (v.empty()) return;
     v[0]=v[0].normalize();
     ctx.startBlock(name);
     displayRational(ctx,v[0]);
@@ -214,16 +225,18 @@ dpyResolutionType(OutputContext &ctx, const char *name, const IFDEntry &e, const
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
     const char *resolution_unit = "???";
-    switch (v[0]) {
-    case 1:
-	resolution_unit = "???";
-	break;
-    case 2:
-	resolution_unit = "Inch";
-	break;
-    case 3:
-	resolution_unit = "Centimeter";
-	break;
+    if (!v.empty()) {
+        switch (v[0]) {
+        case 1:
+            resolution_unit = "???";
+            break;
+        case 2:
+            resolution_unit = "Inch";
+            break;
+        case 3:
+            resolution_unit = "Centimeter";
+            break;
+        }
     }
     ctx.setContextValue("resolutionUnit", resolution_unit);
 }
@@ -261,6 +274,7 @@ const char *findLookup(int key, const void *table) {
 void
 dpyUnsignedLookup(OutputContext &ctx, const char *name, const IFDEntry &e, const void*tbl) {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.empty()) return;
     ctx.startBlock(name);
     const char *val = findLookup((int)v[0], tbl);
     if (val) {
@@ -274,6 +288,7 @@ dpyUnsignedLookup(OutputContext &ctx, const char *name, const IFDEntry &e, const
 void
 dpyUndefinedLookup(OutputContext &ctx, const char *name, const IFDEntry &e, const void*tbl) {
     vector<unsigned char> v = e.getOPAQUE();
+    if (v.empty()) return;
     ctx.startBlock(name);
     const char *val = findLookup((int)v[0], tbl);
     if (val) {
@@ -302,6 +317,7 @@ void
 dpyExifAperture(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffRATIONAL> v = e.getRATIONAL();
+    if (v.empty()) return;
     ctx.startBlock(name);
     double a = v[0];
     double f = pow(M_SQRT2, a);
@@ -316,6 +332,7 @@ void
 dpyExifShutter(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffSRATIONAL> v = e.getSRATIONAL();
+    if (v.empty()) return;
     ctx.startBlock(name);
     double a = v[0];
     if (a > 0.0) {
@@ -335,7 +352,9 @@ dpyRationalAsDouble(OutputContext &ctx, const char *name, const IFDEntry &e, con
 
     if (e.getType() == tSRATIONAL) {
 	vector<tiffSRATIONAL> v = e.getSRATIONAL();
-	if (v[0].getDenominator() == 0) {
+	if (v.empty()) {
+	    ctx.os() << "Unknown";
+	} else if (v[0].getDenominator() == 0) {
 	    ctx.os() << "Infinity";
 	} else {
 	    double a = v[0];
@@ -344,7 +363,9 @@ dpyRationalAsDouble(OutputContext &ctx, const char *name, const IFDEntry &e, con
 	}
     } else {
 	vector<tiffRATIONAL> v = e.getRATIONAL();
-	if (v[0].getDenominator() == 0) {
+	if (v.empty()) {
+	    ctx.os() << "Unknown";
+	} else if (v[0].getDenominator() == 0) {
 	    ctx.os() << "Infinity";
 	} else {
 	    double a = v[0];
@@ -360,6 +381,7 @@ void
 dpyOlymSpecialMode(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.size() < 2) return;
     ctx.startBlock(name);
     switch (v[0]) {
     case 0: ctx.os() << "Normal"; break;
@@ -370,7 +392,7 @@ dpyOlymSpecialMode(OutputContext &ctx, const char *name, const IFDEntry &e, cons
 	ctx.os() << "Unknown (" << v[0] << ")"; break;
     }
     ctx.os() << "; Seq " << v[1];
-    if (v[0] == 3) {
+    if (v[0] == 3 && v.size() >= 3) {
 	switch(v[2]) {
 	case 1: ctx.os() << " Left -> Right"; break;
 	case 2: ctx.os() << " Right -> Left"; break;
@@ -387,6 +409,7 @@ void
 dpyOlymZoom(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffRATIONAL> v = e.getRATIONAL();
+    if (v.empty()) return;
     ctx.startBlock(name);
     double a = v[0];
     if (a == 0.0) {
@@ -414,6 +437,7 @@ void
 dpyCanonBlock1(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.size() < 33) v.resize(33, 0);
 
     try {
 	int n = v[0] / 2;
@@ -542,6 +566,7 @@ dpyCanonBlock1(OutputContext &ctx, const char *name, const IFDEntry &e, const vo
 extern void dpyCanonBlock4(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.size() < 16) v.resize(16, 0);
 
     try {	
 //	int n = v[0] / 2;
@@ -586,6 +611,7 @@ extern void dpyCanonBlock4(OutputContext &ctx, const char *name, const IFDEntry
 extern void dpyCanonImageNumber(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.empty()) return;
 
     try {
 	unsigned long n = v[0];
@@ -607,6 +633,7 @@ extern void dpyCanonImageNumber(OutputContext &ctx, const char *name, const IFDE
 extern void dpyCanonSerialNumber(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.empty()) return;
 
     try {
 	unsigned long n = v[0];
@@ -623,6 +650,7 @@ extern void dpyCanonSerialNumber(OutputContext &ctx, const char *name, const IFD
 extern void dpyCasioDistance(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.empty()) return;
     
     const char* units = "mm";
     double dist = double(v[0]);
@@ -644,8 +672,9 @@ extern void dpyCasioDistance(OutputContext &ctx, const char *name, const IFDEntr
 
 extern void dpyExifFlash(OutputContext &ctx, const char *name, const IFDEntry &e, const void*)
 {
-    ctx.startBlock(name);
     vector<tiffUNSIGNED> v = e.getUVALUE();
+    if (v.empty()) return;
+    ctx.startBlock(name);
     
     if (v[0] & 0x01) {
 	ctx.os() << "Flash Fired; ";
@@ -707,7 +736,7 @@ extern void dpyZoomRatio(OutputContext &ctx, const char *name, const IFDEntry &e
     if (e.getType() == tSRATIONAL) {
 	vector<tiffSRATIONAL> v = e.getSRATIONAL();
 	
-	if (v[0].getNumerator() == 0) {
+	if (v.empty() || v[0].getNumerator() == 0) {
 	    ctx.os() << "None";
 	} else {
 	    displayRational(ctx, v[0]);
@@ -716,7 +745,7 @@ extern void dpyZoomRatio(OutputContext &ctx, const char *name, const IFDEntry &e
     } else {
 	vector<tiffRATIONAL> v = e.getRATIONAL();
 
-	if (v[0].getNumerator() == 0) {
+	if (v.empty() || v[0].getNumerator() == 0) {
 	    ctx.os() << "None";
 	} else {
 	    displayRational(ctx, v[0]);
@@ -734,7 +763,7 @@ extern void dpyRationalDistance(OutputContext &ctx, const char *name, const IFDE
     if (e.getType() == tSRATIONAL) {
 	vector<tiffSRATIONAL> v = e.getSRATIONAL();
 	
-	if (v[0].getNumerator() == 0) {
+	if (v.empty() || v[0].getNumerator() == 0) {
 	    ctx.os() << "Unknown";
 	} else if (v[0].getDenominator() == 0) {
 	    ctx.os() << "Infinity";
@@ -745,7 +774,7 @@ extern void dpyRationalDistance(OutputContext &ctx, const char *name, const IFDE
     } else {
 	vector<tiffRATIONAL> v = e.getRATIONAL();
 
-	if (v[0].getNumerator() == 0) {
+	if (v.empty() || v[0].getNumerator() == 0) {
 	    ctx.os() << "Unknown";
 	} else if (v[0].getDenominator() == 0) {
 	    ctx.os() << "Infinity";
@@ -764,7 +793,7 @@ extern void dpy35mmFocal(OutputContext &ctx, const char *name, const IFDEntry &e
 
     vector<tiffUNSIGNED> v = e.getUVALUE();
 
-    if (v[0] == 0) {
+    if (v.empty() || v[0] == 0) {
 	ctx.os() << "Unknown";
     } else {
 	ctx.os() << v[0] << "mm";
@@ -776,6 +805,7 @@ extern void dpy35mmFocal(OutputContext &ctx, const char *name, const IFDEntry &e
 void
 dpyNikonFocusPosition(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) {
     vector<unsigned char> v = e.getOPAQUE();
+    if (v.size() < 2) return;
     ctx.startBlock(name);
     const char *val = findLookup((int)v[1], lookFocusPosition);
     if (val) {
@@ -842,6 +872,7 @@ void
 dpyNikkorLensInfo(OutputContext &ctx, const char *name, 
 		  const IFDEntry &e, const void*) {
     vector<unsigned char> v = e.getOPAQUE();
+    if (v.size() <= 0x17) return;
     ctx.startBlock(name);
 
     double d;
--- a/dataifdentry.cc
+++ b/dataifdentry.cc
@@ -116,9 +116,10 @@ _DataIFDEntry::getSTRING() const
     vector<string> v;
     if (getRawType() != tASCII) {return v;}
     char tmpbuf[1024];
+    size_t size = (value_count < 1023 ? value_count : 1023);
     source.seek(offset);
-    source.getData((unsigned char *)tmpbuf, value_count);
-    tmpbuf[value_count] = 0;
+    source.getData((unsigned char *)tmpbuf, size);
+    tmpbuf[size] = 0;
     v.push_back(string(tmpbuf));
     return v;
 }
--- a/dpyfuncs.cc
+++ b/dpyfuncs.cc
@@ -457,7 +457,7 @@ dpyCanonBlock1(OutputContext &ctx, const char *name, const IFDEntry &e, const vo
 		"Auto + Red-Eye Reduction", "On + Red-Eye Reduction"
 	    };
 	    if (v[4] <= 6)
-		fmt(ctx, "Flash Mode", flashmodes[v[4]]);
+		fmt(ctx, "Flash Mode", flashmodes[v[4] - 1]);
 	    else if (v[4] == 16)
 		fmt(ctx, "Flash Mode", "External");
 	} else
