delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2019/08/11/08:29:33

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
X-Recipient: djgpp AT delorie DOT com
X-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1565526333;
bh=x3L/srTnKJUWSD4n6P/JDnuNA1eUhJ16wQCpZLPDrIs=;
h=To:Subject:From:Date:Message-ID;
b=sG6EZ/AJJx11WaY06V+0/qX8+7YvD06WCuoNcYUTAus66bXs2FLNrasc8msoLLXlE
BA7X+HofPgkM2iSAWDM4lReF/5xnbQQE1eQ6blJ0WOPcuAfw1rYBwKJEYAdntLHij8
a39KNduTH3o7adTdicEOQ1La2GYP48GOL4cFGELg=
Authentication-Results: mxback5o.mail.yandex.net; dkim=pass header.i=@yandex.ru
From: "Stas Sergeev (stsp2 AT yandex DOT ru) [via djgpp AT delorie DOT com]" <djgpp AT delorie DOT com>
Subject: [patch] fix empty environment handling
To: djgpp AT delorie DOT com
Message-ID: <93e55dbd-cbd4-9de1-2c29-c7bb08d872f0@yandex.ru>
Date: Sun, 11 Aug 2019 15:25:32 +0300
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101
Thunderbird/60.6.1
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com

This is a multi-part message in MIME format.
--------------F8DB424F010DFA1EB4A14339
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 7bit

Hello.

There are several djgpp-written shells in the
wild, and they are troubled with the fact that
djgpp does not handle the empty environment.

Every DOS has its own way of presenting the
empty environment:
- FreeDOS presents it as "0xd 0x1 0x0 <argv0>"
which is the worst possible representation.
Fortunately they noticed that all shells crash,
and added a work-around to set "PATH=."
instead of keeping the env empty. No work-around
is therefore needed on djgpp side.
- fdpp (freedos-plus-plus) presents an empty
env as "0x0 0x1 0x0 <argv0>". The attached
patch handles this by moving the env-traversion
loop condition check before the loop itself.
- PC/MS-DOS presents an empty env as 0 in
the PSP:2c. For that condition, the attached patch
adds a check and the adequate error message.
The only work-around is to use "set PATH=."
in config.sys.
- DR-DOS always puts 0 in PSP:2c, regardless
of whether the env is empty or not. No easy
work-around for that one, other than to run
the djgpp-written shell via the native shell.

Patch attached.



--------------F8DB424F010DFA1EB4A14339
Content-Type: text/x-patch;
 name="0001-fix-handling-of-empty-environment.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="0001-fix-handling-of-empty-environment.patch"

From 65d7caeb32f21597938f49364737789727516fdb Mon Sep 17 00:00:00 2001
From: Stas Sergeev <stsp AT users DOT sourceforge DOT net>
Date: Sun, 4 Aug 2019 01:25:38 +0300
Subject: [PATCH] fix handling of empty environment

Currently if the DOS environment is empty (can happen
when starting command.com), djgpp startup produces the
corrupted environment. This patch fixes it by checking
the loop end condition before loop action.

Another problematic case is the missing environment segment.
In this case there is no work-around, so the error msg
is printed and the program terminates.
---
 src/libc/crt0/crt1.c | 12 +++++++-----
 src/stub/stub.asm    | 16 +++++++++++++---
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/libc/crt0/crt1.c b/src/libc/crt0/crt1.c
index f0ba9919..37c7dedb 100644
--- a/src/libc/crt0/crt1.c
+++ b/src/libc/crt0/crt1.c
@@ -128,31 +128,33 @@ char *__dos_argv0;
 static void
 setup_environment(void)
 {
-  char *dos_environ = alloca(_stubinfo->env_size), *cp;
+  char *dos_environ, *cp;
   short env_selector;
   int env_count=0;
+
+  dos_environ = alloca(_stubinfo->env_size);
   movedata(_stubinfo->psp_selector, 0x2c, ds, (int)&env_selector, 2);
   movedata(env_selector, 0, ds, (int)dos_environ, _stubinfo->env_size);
   cp = dos_environ;
-  do {
+  while (*cp) { /* repeat until two NULs */
     env_count++;
     while (*cp) cp++; /* skip to NUL */
     cp++; /* skip to next character */
-  } while (*cp); /* repeat until two NULs */
+  }
   _environ = (char **)malloc((env_count+1) * sizeof(char *));
   if (_environ == 0)
     return;
 
   cp = dos_environ;
   env_count = 0;
-  do {
+  while (*cp) { /* repeat until two NULs */
     /* putenv assumes each string is malloc'd */
     _environ[env_count] = (char *)malloc(strlen(cp)+1);
     strcpy(_environ[env_count], cp);
     env_count++;
     while (*cp) cp++; /* skip to NUL */
     cp++; /* skip to next character */
-  } while (*cp); /* repeat until two NULs */
+  }
   _environ[env_count] = 0;
 
   /*
diff --git a/src/stub/stub.asm b/src/stub/stub.asm
index 62dee9e9..76b2edd6 100644
--- a/src/stub/stub.asm
+++ b/src/stub/stub.asm
@@ -160,13 +160,21 @@ resize_again:
 ;  Scan environment for "PATH=" and the stub's full name after environment
 
 	mov	es, es:[0x2c]		; get environment segment
+	mov	di, es
+	or	di, di			; check if no env
+	jnz	@f1
+	mov	al, 111
+	mov	dx, msg_no_env
+	jmpl	error
+@f1:
 	xor	di, di			; begin search for NUL/NUL (di = 0)
 ;	mov	cx, 0xff04		; effectively `infinite' loop
 	xor 	al, al
-	.db	0xa9			; "test ax,...." -- skip 2 bytes
+	jmp	@f1
 scan_environment:
 	repne
 	scasb				; search for NUL
+@f1:
 	cmpw	es:[di], 0x4150		; "PA"
 	jne	not_path
 	scasw
@@ -182,6 +190,8 @@ not_path:
 	scasb
 	jne	scan_environment	; no, still environment
 	scasw				; adjust pointer to point to prog name
+	push	es
+	push	di
 
 ;; When we are spawned from a program which has more than 20 handles in use,
 ;; all the handles passed to us by DOS are taken (since only the first 20
@@ -199,8 +209,6 @@ not_path:
 ;-----------------------------------------------------------------------------
 ;  Get DPMI information before doing anything 386-specific
 
-	push	es
-	push	di
 	xor	cx, cx			; flag for load attempt set cx = 0
 	jz	@f2			; We always jump, shorter than jmp
 @b1:
@@ -828,6 +836,8 @@ msg_not_exe:
 	.db	": not EXE$"
 msg_not_coff:
 	.db	": not COFF (Check for viruses)$"
+msg_no_env:
+	.db	"no environment segment$"
 msg_no_dpmi:
 	.db	"no DPMI - Get csdpmi*b.zip$"
 msg_no_dos_memory:
-- 
2.20.1



--------------F8DB424F010DFA1EB4A14339--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019