diff mbox series

[5/5] mingw: use {gm,local}time_s as backend for {gm,local}time_r

Message ID 2c39f9a04f98fc3d365c80ce57e8edce305846fb.1574867409.git.congdanhqx@gmail.com (mailing list archive)
State New, archived
Headers show
Series drop non-reentrant time usage | expand

Commit Message

Đoàn Trần Công Danh Nov. 27, 2019, 3:13 p.m. UTC
Since Windows doesn't provide gmtime_r(3) and localtime_r(3),
we're providing a compat version by using non-reentrant gmtime(3) and
localtime(3) as backend. Then, we copy the returned data into the
buffer.

By doing that, in case of failure, we will dereference a NULL pointer
returned by gmtime(3), and localtime(3), and we always return a valid
pointer instead of NULL.

Drop the memcpy(3) by using gmtime_s, and localtime_s as backend on
Windows, and make sure we will return NULL in case of failure.

Cc: Johannes Sixt <j6t@kdbg.org>
Cc: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Doan Tran Cong Danh <congdanhqx@gmail.com>
---
 compat/mingw.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

Comments

Johannes Schindelin Nov. 27, 2019, 7:35 p.m. UTC | #1
Hi Danh,

On Wed, 27 Nov 2019, Doan Tran Cong Danh wrote:

> Since Windows doesn't provide gmtime_r(3) and localtime_r(3),
> we're providing a compat version by using non-reentrant gmtime(3) and
> localtime(3) as backend. Then, we copy the returned data into the
> buffer.
>
> By doing that, in case of failure, we will dereference a NULL pointer
> returned by gmtime(3), and localtime(3), and we always return a valid
> pointer instead of NULL.
>
> Drop the memcpy(3) by using gmtime_s, and localtime_s as backend on

s/and localtime_s/and use localtime_s()/

Otherwise, this looks good to me, thank you!

Ciao,
Dscho

> Windows, and make sure we will return NULL in case of failure.
>
> Cc: Johannes Sixt <j6t@kdbg.org>
> Cc: Johannes Schindelin <Johannes.Schindelin@gmx.de>
> Signed-off-by: Doan Tran Cong Danh <congdanhqx@gmail.com>
> ---
>  compat/mingw.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/compat/mingw.c b/compat/mingw.c
> index fe609239dd..7b21f4eee5 100644
> --- a/compat/mingw.c
> +++ b/compat/mingw.c
> @@ -1,6 +1,7 @@
>  #include "../git-compat-util.h"
>  #include "win32.h"
>  #include <conio.h>
> +#include <errno.h>
>  #include <wchar.h>
>  #include "../strbuf.h"
>  #include "../run-command.h"
> @@ -986,16 +987,16 @@ int pipe(int filedes[2])
>
>  struct tm *gmtime_r(const time_t *timep, struct tm *result)
>  {
> -	/* gmtime() in MSVCRT.DLL is thread-safe, but not reentrant */
> -	memcpy(result, gmtime(timep), sizeof(struct tm));
> -	return result;
> +	if (gmtime_s(result, timep) == 0)
> +		return result;
> +	return NULL;
>  }
>
>  struct tm *localtime_r(const time_t *timep, struct tm *result)
>  {
> -	/* localtime() in MSVCRT.DLL is thread-safe, but not reentrant */
> -	memcpy(result, localtime(timep), sizeof(struct tm));
> -	return result;
> +	if (localtime_s(result, timep) == 0)
> +		return result;
> +	return NULL;
>  }
>
>  char *mingw_getcwd(char *pointer, int len)
> --
> 2.24.0.158.gd77a74f4dd.dirty
>
>
Johannes Schindelin Nov. 27, 2019, 7:39 p.m. UTC | #2
Hi Danh,

On Wed, 27 Nov 2019, Doan Tran Cong Danh wrote:

> diff --git a/compat/mingw.c b/compat/mingw.c
> index fe609239dd..7b21f4eee5 100644
> --- a/compat/mingw.c
> +++ b/compat/mingw.c
> @@ -1,6 +1,7 @@
>  #include "../git-compat-util.h"
>  #include "win32.h"
>  #include <conio.h>
> +#include <errno.h>

I actually overlooked this. Please drop this hunk, it should not be needed
(and might break things in the MSVC build).

Thanks,
Dscho

>  #include <wchar.h>
>  #include "../strbuf.h"
>  #include "../run-command.h"
> @@ -986,16 +987,16 @@ int pipe(int filedes[2])
>
>  struct tm *gmtime_r(const time_t *timep, struct tm *result)
>  {
> -	/* gmtime() in MSVCRT.DLL is thread-safe, but not reentrant */
> -	memcpy(result, gmtime(timep), sizeof(struct tm));
> -	return result;
> +	if (gmtime_s(result, timep) == 0)
> +		return result;
> +	return NULL;
>  }
>
>  struct tm *localtime_r(const time_t *timep, struct tm *result)
>  {
> -	/* localtime() in MSVCRT.DLL is thread-safe, but not reentrant */
> -	memcpy(result, localtime(timep), sizeof(struct tm));
> -	return result;
> +	if (localtime_s(result, timep) == 0)
> +		return result;
> +	return NULL;
>  }
>
>  char *mingw_getcwd(char *pointer, int len)
> --
> 2.24.0.158.gd77a74f4dd.dirty
>
>
Đoàn Trần Công Danh Nov. 28, 2019, 12:05 p.m. UTC | #3
On 2019-11-27 20:39:27+0100, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> Hi Danh,
> 
> On Wed, 27 Nov 2019, Doan Tran Cong Danh wrote:
> 
> > diff --git a/compat/mingw.c b/compat/mingw.c
> > index fe609239dd..7b21f4eee5 100644
> > --- a/compat/mingw.c
> > +++ b/compat/mingw.c
> > @@ -1,6 +1,7 @@
> >  #include "../git-compat-util.h"
> >  #include "win32.h"
> >  #include <conio.h>
> > +#include <errno.h>
> 
> I actually overlooked this. Please drop this hunk, it should not be needed
> (and might break things in the MSVC build).

Oops, originally, I intended to reset errno after {gm,local}time_s
Found out it's unneccessary later but I forgot to drop this hunk.
I'll fix it.
diff mbox series

Patch

diff --git a/compat/mingw.c b/compat/mingw.c
index fe609239dd..7b21f4eee5 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1,6 +1,7 @@ 
 #include "../git-compat-util.h"
 #include "win32.h"
 #include <conio.h>
+#include <errno.h>
 #include <wchar.h>
 #include "../strbuf.h"
 #include "../run-command.h"
@@ -986,16 +987,16 @@  int pipe(int filedes[2])
 
 struct tm *gmtime_r(const time_t *timep, struct tm *result)
 {
-	/* gmtime() in MSVCRT.DLL is thread-safe, but not reentrant */
-	memcpy(result, gmtime(timep), sizeof(struct tm));
-	return result;
+	if (gmtime_s(result, timep) == 0)
+		return result;
+	return NULL;
 }
 
 struct tm *localtime_r(const time_t *timep, struct tm *result)
 {
-	/* localtime() in MSVCRT.DLL is thread-safe, but not reentrant */
-	memcpy(result, localtime(timep), sizeof(struct tm));
-	return result;
+	if (localtime_s(result, timep) == 0)
+		return result;
+	return NULL;
 }
 
 char *mingw_getcwd(char *pointer, int len)