On 07/09/13 11:26, Gary Ching-Pang Lin wrote:
> Per gmtime manpage, tm_mon is the number of months since January
> while MonthNo is the month of the year, so tm_mon should be MonthNo-1.
>
> Also, tm_mday is the day of the month, and DayNo is the number of
> days since the first day of the month. Assigning DayNo+1 to tm_mday
> to fix the definition.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Gary Ching-Pang Lin <g...@suse.com>
> ---
>  CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c 
> b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
> index 805e6b4..15be4ef 100644
> --- a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
> +++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
> @@ -154,8 +154,8 @@ struct tm * gmtime (const time_t *timer)
>      }
>    }
>
> -  GmTime->tm_mon  = (int) MonthNo;
> -  GmTime->tm_mday = (int) DayNo;
> +  GmTime->tm_mon  = (int) MonthNo - 1;
> +  GmTime->tm_mday = (int) DayNo + 1;
>
>    GmTime->tm_isdst  = 0;
>    GmTime->tm_gmtoff = 0;
>

"DayNo" is the number of whole days passed since the Epoch.

In the gmtime() function, the first loop subtracts whole years. At the
end of the loop, DayNo may be zero (eg. 01-Jan-1971). After the loop,
"DayNo" contains the number of whole days passed in the new year.

The second loop wants to find out the number of whole months passed in
the new year, and the number of remaining days. Again, the number of
days remaining in the month could be 0 in theory (eg. for 01-Feb-1970).

  for (MonthNo = 12; MonthNo > 1; MonthNo--) {
    if (DayNo > CumulativeDays[IsLeap(Year)][MonthNo]) {
      DayNo = (UINT16) (DayNo - (UINT16) 
(CumulativeDays[IsLeap(Year)][MonthNo]));
      break;
    }
  }

For 01-Feb-1970, DayNo == 31 before the second loop. In the second loop,
for MonthNo==2, CumulativeDays[0][2] == 31, hence we don't break out,
and MonthNo is decreased to 1. Thereafter the controlling expression
stops the loop (with MonthNo==1, DayNo==31):

         should be  pre-patch  post-patch
tm_mon           1          1           0
tm_mday          1         31          32

I think both pre-patch and post-patch results are wrong (although the
post-patch version is correct "quantitatively", as Feb 1st is in fact
the 32nd day of January).

The thing to fix (in addition to the patch) is the relational operator
in the loop: if the number of our remaining *whole* days is greater than
*or equal to* the cumulative days up to and including MonthNo, then
month MonthNo itself has passed too. (Note that MonthNo==12 corresponds
to November.)

When the second loop, modified thus, terminates, MonthNo==1 implies that
*stricly less* than 31 days have passed in the new year, hence we're
still in January. DayNo keeps its meaning (and MonthNo==1 && DayNo==0
corresponds to Jan 1st).

I think the patch is a step in the right direction but incomplete; I
suggest:

diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c 
b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
index 805e6b4..6422d61 100644
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/TimerWrapper.c
@@ -148,14 +148,14 @@ struct tm * gmtime (const time_t *timer)
   GmTime->tm_yday = (int) DayNo;

   for (MonthNo = 12; MonthNo > 1; MonthNo--) {
-    if (DayNo > CumulativeDays[IsLeap(Year)][MonthNo]) {
+    if (DayNo >= CumulativeDays[IsLeap(Year)][MonthNo]) {
       DayNo = (UINT16) (DayNo - (UINT16) 
(CumulativeDays[IsLeap(Year)][MonthNo]));
       break;
     }
   }

-  GmTime->tm_mon  = (int) MonthNo;
-  GmTime->tm_mday = (int) DayNo;
+  GmTime->tm_mon  = (int) MonthNo - 1;
+  GmTime->tm_mday = (int) DayNo + 1;

   GmTime->tm_isdst  = 0;
   GmTime->tm_gmtoff = 0;

This is identical to your patch for all days except for Feb 1st, Mar
1st, ... Dec 1st, where my suggested version returns DayNo==0
(-->tm_mday==1), and the next month relative to yours.

Laszlo

------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to