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=1570229981; bh=0ecDfZyc1lcRe2cIvMXz9U2ALtXGCmq+Mx2PIa424xs=; h=In-Reply-To:To:From:Subject:Date:References:Message-ID; b=HYDSJj9p7FPk2lm7WFPW5Fy7hj+iB1ZHNZDq6yo9gc1ZmXQexhmOOWSNBO952URmi M9mp3CjvjgWlKYbUddRGs3eAP/YhcS2NuUI5uc1bFAnbZll0O8+CZJ9zSdhsMf+XdP w4uOvkH9fwejf6bdHaCam1szHQIOYyGZbzvaD0nM= Authentication-Results: mxback9q.mail.yandex.net; dkim=pass header.i=@yandex.ru Subject: [patch v2] fix empty environment handling From: "stsp (stsp2 AT yandex DOT ru) [via djgpp AT delorie DOT com]" To: djgpp AT delorie DOT com References: <93e55dbd-cbd4-9de1-2c29-c7bb08d872f0 AT yandex DOT ru> Message-ID: <9a9775ad-255a-407c-de95-3b503dc2046a@yandex.ru> Date: Sat, 5 Oct 2019 01:59:39 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 MIME-Version: 1.0 In-Reply-To: <93e55dbd-cbd4-9de1-2c29-c7bb08d872f0@yandex.ru> Content-Type: multipart/mixed; boundary="------------EF70800FA20613BE8EBE4296" Content-Language: en-MW Reply-To: djgpp AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk This is a multi-part message in MIME format. --------------EF70800FA20613BE8EBE4296 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Hello, here is the v2 version of the environment fix. Difference with v1: just this line: + .db "no environment segment$" was replaced with: + .db "no envseg$" Why, you ask? Is such a change worth a patch re-send? Well, as was pointed to me by DJ (in another ML), the stub must be within 2K in size.Unfortunately my msg exceeded that limit. I've shortened it to stay within 2K. Quite an unfortunate limitation, if you ask me. --------------EF70800FA20613BE8EBE4296 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 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 envseg$" msg_no_dpmi: .db "no DPMI - Get csdpmi*b.zip$" msg_no_dos_memory: -- 2.20.1 --------------EF70800FA20613BE8EBE4296--