Targeted minimal fix for security issue in CVE-2020-9589. am: 8051967ac1 am: 17f4b85725 am: ab47f56729 am: 0d886a49d3 am: ecb2edbc9a am: dd40fd0c8c am: 234929445c am: f0ff5a6b46

Original change: https://googleplex-android-review.googlesource.com/c/platform/external/dng_sdk/+/11464172

Change-Id: Ib181022cad844fdf9b1c2c015723d7b85a5de7a2
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+  license_type: NOTICE
+}
diff --git a/source/dng_date_time.cpp b/source/dng_date_time.cpp
index bede131..b143181 100644
--- a/source/dng_date_time.cpp
+++ b/source/dng_date_time.cpp
@@ -806,32 +806,44 @@
 		#if qMacOS
 		
 		CFTimeZoneRef zoneRef = CFTimeZoneCopyDefault ();
-		
+
+		CFReleaseHelper<CFTimeZoneRef> zoneRefDeleter (zoneRef);
+
 		if (zoneRef)
 			{
-			
-			CFGregorianDate gregDate;
 
-			gregDate.year   = dt.fYear;
-			gregDate.month  = (SInt8) dt.fMonth;
-			gregDate.day    = (SInt8) dt.fDay;
-			gregDate.hour   = (SInt8) dt.fHour;
-			gregDate.minute = (SInt8) dt.fMinute;
-			gregDate.second = (SInt8) dt.fSecond;
-			
-			CFAbsoluteTime absTime = CFGregorianDateGetAbsoluteTime (gregDate, zoneRef);
-			
-			CFTimeInterval secondsDelta = CFTimeZoneGetSecondsFromGMT (zoneRef, absTime);
-		
-			CFRelease (zoneRef);
-			
-			result.SetOffsetSeconds (Round_int32 (secondsDelta));
-			
-			if (result.IsValid ())
+			// New path that doesn't use deprecated CFGregorian-based APIs.
+
+			CFCalendarRef calendar =
+				CFCalendarCreateWithIdentifier (kCFAllocatorDefault,
+												kCFGregorianCalendar);
+
+			CFReleaseHelper<CFCalendarRef> calendarDeleter (calendar);
+
+			CFAbsoluteTime absTime;
+
+			if (CFCalendarComposeAbsoluteTime (calendar,
+											   &absTime,
+											   "yMdHms",
+											   dt.fYear,
+											   dt.fMonth,
+											   dt.fDay,
+											   dt.fHour,
+											   dt.fMinute,
+											   dt.fSecond))
 				{
-				return result;
+
+				CFTimeInterval secondsDelta = CFTimeZoneGetSecondsFromGMT (zoneRef, absTime);
+
+				result.SetOffsetSeconds (Round_int32 (secondsDelta));
+
+				if (result.IsValid ())
+					{
+					return result;
+					}
+
 				}
-			
+
 			}
 		
 		#endif
diff --git a/source/dng_utils.h b/source/dng_utils.h
index 691f0b9..db38599 100644
--- a/source/dng_utils.h
+++ b/source/dng_utils.h
@@ -1259,6 +1259,46 @@
 
 /*****************************************************************************/
 
+#if qMacOS
+
+/*****************************************************************************/
+
+template<typename T>
+class CFReleaseHelper
+	{
+
+	private:
+
+		T fRef;
+
+	public:
+
+		CFReleaseHelper (T ref)
+			:	fRef (ref)
+			{
+			}
+
+		~CFReleaseHelper ()
+			{
+			if (fRef)
+				{
+				CFRelease (fRef);
+				}
+			}
+
+		T Get () const
+			{
+			return fRef;
+			}
+
+	};
+
+/*****************************************************************************/
+
+#endif	// qMacOS
+
+/*****************************************************************************/
+
 #endif
 	
 /*****************************************************************************/