Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - kosh

#1
Whither newLISP? / mat BUG
July 26, 2016, 01:33:45 PM
Hello Lutz.



"mat" function returns incorrect value on 64-bit system.

(This problem is confirmed on Windows and macOSX both 32/64-bit)


C:>newlisp -v
newLISP v.10.7.0 32-bit on Windows IPv4/6 UTF-8 libffi.

C:>newlisp -e "(mat * '((1 2 3) (4 5 6)) -1)"
((-1 -2 -3) (-4 -5 -6))

C:>newlisp-x64 -v
newLISP v.10.7.0 64-bit on Windows IPv4/6 UTF-8 libffi.

C:>newlisp-x64 -e "(mat * '((1 2 3) (4 5 6)) -1)"
((1.844674407370955e+019 3.68934881474191e+019 5.534023222112866e+019) (7.378697629483821e+019
  9.223372036854776e+019 1.106804644422573e+020))


Regards.
#2
Whither newLISP? / Can not load empty file
September 16, 2015, 10:31:00 AM
Hi.



A error occurred in loadin empty file. It should be return a nil?


$ touch empty.lsp
$ newlisp
newLISP v.10.6.3 64-bit on OSX IPv4/6 UTF-8 libffi, options: newlisp -h

> (load "empty.lsp")
ERR: problem accessing file in function load : "empty.lsp"
> (eval-string "")  ; passing empty string
nil
#3
`unpack` function with LIBFFI segfault when variable type "char*" is NULL.


struct string {
    char *ptr;
    size_t len;
};


newLISP v.10.6.2 32-bit on Win32 IPv4/6 UTF-8 libffi, options: newlisp -h

> (struct '_struct_string "char*" "long")
_struct_string
> (setf s (pack _struct_string 0 0))
"0000000000000000"
> (unpack _struct_string s)
Segment fault


I expected following behavior:


> (unpack _struct_string s)
(nil 0)


How to avoid something this?



(It can use `unpack` without LIBFFI. but code will be more complex.)
#4
newLISP and the O.S. / mingw64 build patch
February 14, 2015, 11:16:01 AM
Hi Lutz.



I wrote patch file for builds with MinGW-w64 gcc.

Changes are following:



- Define UINT as pointer size integer (stdint.h, uintptr_t)

- Use type conversion macros for printf (inttypes.h, PRIdPTR)

- Auto detect 64-bit memory model (LP64/LLP64) using C pre-defined macros

- nl-sock.c: bugfix non initialized var DefaultIn



Patch files can be viewed on GitHub:

https://github.com/kosh04/newlisp/compare/feature/mingw-w64">https://github.com/kosh04/newlisp/compa ... /mingw-w64">https://github.com/kosh04/newlisp/compare/feature/mingw-w64



(p.s. BBS attachment fails with message The extension diff is not allowed.)



Build and Test (`make testall`) passed under the following platform:



- Win7 Home amd64

-- TDM-GCC (mingw-w64 gcc 4.9.1)

-- MinGW gcc 4.8.1

-- cygwin32 gcc 4.9.2

-- cygwin64 gcc 4.9.2

- Mac OSX clang



However, this patch have some problems:



- stdint.h, inttypes.h headers available in ISO C99. but newLISP C source seem to C90.

- win32-path.c: an incomplete compatibility between `struct stat` and `struct _stat`.

- nl-sock.c: UINT type is name conflict in ws2tcpip.h.

  This patch provides the temporary workaround using push_macro/pop_macro.

  If you don't like this way, better to rename the UINT to another name (e.g. `typedef uintptr_t nl_int;`)



All reviews are welcome. Thanks.
#5
newLISP and the O.S. / mingw patch
August 24, 2014, 09:45:44 AM
Hi Lutz.



This patch is solves about 2 problems on MinGW compile.



1. _WIN32_WINNT macros must define before windows.h and other headers



Because of most of mingw headers (stdio.h, signal.h, ...) include _mingw.h and sdkddkver.h.

And define _WIN32_WINNT there if not defined.


diff --git a/newlisp.h b/newlisp.h
index d7537fd..23ce42a 100644
--- a/newlisp.h
+++ b/newlisp.h
@@ -159,6 +159,16 @@ This is for 64bit large file support (LFS),
 #define _FILE_OFFSET_BITS 64
 #endif
 
+#ifdef WINDOWS
+/* NOTE:
+ * Windows XP [0x0501] end of support on 2014/04/08
+ * WIndows Vista [0x0600] support ends on 2017/04/11
+ */
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#endif
+#endif
+
 #include <signal.h>
 #include <errno.h>
 #include <stdio.h>
@@ -188,9 +198,6 @@ This is for 64bit large file support (LFS),
 #endif
 
 #ifdef WINDOWS
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
 #include <windef.h>
 #include <winbase.h>
 #else


2. time_t and struct timeval bit size



Windows time_t is now a 64-bit integer by default.

Therefore sizeof(UINT) and sizeof(time_t) are not equal on 32-bit windows.

http://msdn.microsoft.com/en-us/library/1f4c8f33.aspx">//http://msdn.microsoft.com/en-us/library/1f4c8f33.aspx



And struct timeval tv.tv_sec is different type long (windows) and time_t (linux).


diff --git a/nl-filesys.c b/nl-filesys.c
index 99a6c84..5655132 100644
--- a/nl-filesys.c
+++ b/nl-filesys.c
@@ -2454,7 +2454,7 @@ struct tm * ltm;
 char * ct;
 char * fmt;
 ssize_t offset;
-time_t tme;
+UINT tme;
 size_t size;
 
 #ifdef SUPPORT_UTF8
@@ -2474,8 +2474,8 @@ if(params == nilCell)
     }
 else
     {
-    params = getInteger(params, (UINT *)&tme);
-    t = tme;
+    params = getInteger(params, &tme);
+    t = (time_t)tme;
     
     if(params != nilCell)
         {
@@ -2524,10 +2524,12 @@ INT64 microSecTime(void)
 {
 struct timeval tv;
 struct tm * ttm;
+time_t sec;
 
 gettimeofday(&tv, NULL);
 
-ttm = localtime((time_t *)&tv.tv_sec);
+sec = tv.tv_sec;
+ttm = localtime(&sec);
 
 return (ttm->tm_hour * 3600000000LL +
        ttm->tm_min * 60000000LL + ttm->tm_sec * 1000000 +
@@ -2650,6 +2652,7 @@ UINT isdst;
 TIME_ZONE_INFORMATION timeZone;
 #endif
 ssize_t offset = 0;
+time_t sec;
 CELL * cell;
 
 gettimeofday(&tv, NULL); /* get secs and microsecs */
@@ -2681,7 +2684,8 @@ gmtoff = ltm->tm_gmtoff/60;
 GetTimeZoneInformation(&timeZone);
 #endif
 
-ttm = gmtime((time_t *)&tv.tv_sec);
+sec = tv.tv_sec;
+ttm = gmtime(&sec);
 
 cell = stuffIntegerList(
     11,
@@ -2731,10 +2735,12 @@ CELL * p_dateList(CELL * params)
 {
 struct tm *ttm;
 ssize_t timeValue;
+time_t timer;
 CELL * cell;
 
 params = getInteger(params, (UINT*)&timeValue);
-ttm = gmtime((time_t *)&timeValue);
+timer = (time_t)timeValue;
+ttm = gmtime(&timer);
 
 cell = stuffIntegerList(
     8,
@@ -2804,12 +2810,11 @@ dateValue = 367 * year - (7 * (year + ((month + 9) / 12)))/4
 dateValue = dateValue * 24 * 3600 + hour * 3600 + min * 60 + sec
             - 413319296; /* correction for 1970-1-1 */
 
-#ifdef NEWLISP64
 if(dateValue & 0x80000000)
     dateValue = dateValue | 0xFFFFFFFF00000000;
 else
-    dateValue = dateValue & 0xffffffff;
-#endif
+    dateValue = dateValue & 0x00000000ffffffff;
 
 return(dateValue);
 }


Regards.
#6
newLISP and the O.S. / crc32 bug on newlisp 32-bit
July 19, 2014, 11:17:33 PM
crc32 function may return wrong value on 32-bit machine.


> (crc32 "hello")
907060870        ; OK
> (crc32 "HELLO")
-1052482506      ; NG [0xffffffffc1446436]
> (& (crc32 "HELLO") 0x00000000ffffffff)
3242484790       ; OK [0x00000000c144643]


This problem occurs because of difference between internal value and CELL value.



- upadte_crc function (in nl-math.c) returns unsigned 32-bit integer.

- But newlisp's printCell function treats as signed integer.



This solves the crc32 values are always treated as an 64-bit integer.


--- nl-math.c~ 2014-06-04 11:44:59 +0900
+++ nl-math.c 2014-06-20 22:31:07 +0900
@@ -2354,9 +2354,12 @@
 {
 char * data;
 size_t len;
+unsigned int crc;
 
 params = getStringSize(params, &data, &len, TRUE);
-return(stuffInteger(update_crc(0xffffffffL, (unsigned char *)data, (int)len) ^ 0xffffffffL));
+crc = update_crc(0xffffffffL, (unsigned char *)data, (int)len) ^ 0xffffffffL;
+return(stuffInteger64(crc));
 }
#7
Hi Lutz.



I found unusual behavior when 'import' called from url.


newLISP v.10.5.4 32-bit on BSD IPv4/6 UTF-8 libffi, options: newlisp -h

> (setq url "http://lambda.que.jp/files/x.lsp")
> (get-url url)
"(import "libc.so" "printf")n"
> (load url)

ERR: import function not found in function import : "Undefined symbol "_nss_cac
he_cycle_prevention_function""


Perhaps, you should call the dlerror() to clear error code before dlsym().



http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html">http://tldp.org/HOWTO/Program-Library-H ... aries.html">http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html


Quote4.3. dlsym()

...

The standard solution is to call dlerror() first (to clear any error condition that may have existed), then call dlsym() to request a symbol, then call dlerror() again to see if an error occurred. A code snippet would look like this:


dlerror(); /* clear error code */
 s = (actual_type) dlsym(handle, symbol_being_searched_for);
 if ((err = dlerror()) != NULL) {
  /* handle error, the symbol wasn't found */
 } else {
  /* symbol found, its value is in s */
 }



Patch file here:


diff --git a/nl-import.c b/nl-import.c
index a14264f..40a1320 100644
--- a/nl-import.c
+++ b/nl-import.c
@@ -172,6 +172,8 @@ pCell = getCell(type);
 deleteList((CELL *)symbol->contents);
 symbol->contents = (UINT)pCell;

+dlerror();
+
 pCell->contents = (UINT)dlsym(hLibrary, funcName);

 if((error = (char *)dlerror()) != NULL)
#8
newLISP newS / Alternative git repository
October 11, 2013, 04:01:49 AM
Hi.



http://repo.or.cz/w/newlisp/alt-newlisp.git">http://repo.or.cz/w/newlisp/alt-newlisp.git



I forked newlisp mirror repository in repo.or.cz.



These original sources are available here: http://sourceforge.net/projects/newlisp/files/">http://sourceforge.net/projects/newlisp/files/

All commit message are based on doc/CHANGES.



You can view the difference between commits. and clone it.
#9
newLISP and the O.S. / closesocket in MinGW
August 28, 2013, 11:42:14 PM
Hi.



This patch is resolve problems which fail to close the file descriptor.


diff --git a/nl-sock.c b/nl-sock.c
index 00efa7b..9acdaa7 100644
--- a/nl-sock.c
+++ b/nl-sock.c
@@ -1485,7 +1485,12 @@ handle = open(logFile, O_RDWR | O_APPEND | O_BINARY | O_CREAT,
 if(write(handle, text, strlen(text)) < 0) return;
 if(newLine)
     if(write(handle, &LINE_FEED, LINE_FEED_LEN) < 0) return;
+
+#ifdef WINDOWS
+_close(handle);
+#else
 close(handle);
+#endif
 }
 
 
diff --git a/nl-web.c b/nl-web.c
index 518fca0..99b516a 100644
--- a/nl-web.c
+++ b/nl-web.c
@@ -1183,7 +1183,11 @@ switch(type)
             }
 
         transferred = readPayLoad(size, buff, outFile, request);
+#ifdef WINDOWS
+        _close(outFile);
+#else
         close(outFile);
+#endif
 
         if(transferred != -1)
             {


Or, define 'closesocket' function for closing the only socket descriptor.

In this case, patch will become a little bigger: http://pastebin.com/gAYUsp1Y">//http://pastebin.com/gAYUsp1Y


#ifdef WINDOWS
-#define close(s) closesocket(s)
 #else
 #include <sys/socket.h>
 #define SOCKET_ERROR -1
 #define INVALID_SOCKET -1
+#define closesocket(s) close(s)
 #endif
#10
This test code is based on JSON Checker (http://www.json.org/JSON_checker/">http://www.json.org/JSON_checker/)



json-test.lsp: http://pastebin.com/9nqJHSW3">http://pastebin.com/9nqJHSW3



The results are here:


> newlisp -v
newLISP v.10.5.2 32-bit on Win32 IPv4/6 UTF-8 libffi.

> newlisp json-test.lsp
fail1.json -> pass : "A JSON payload should be an object or array, not a string."
fail7.json -> pass : ["Comma after the close"],
fail8.json -> pass : ["Extra close"]]
fail10.json -> pass : {"Extra value after close": true} "misplaced quoted value"
fail13.json -> pass : {"Numbers cannot have leading zeroes": 013}
fail15.json -> pass : ["Illegal backslash escape: x15"]
fail17.json -> pass : ["Illegal backslash escape: 17"]
fail18.json -> pass : [[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
fail25.json -> pass : [" tab character in string "]
fail26.json -> pass : ["tab   character   in  string  "]
fail27.json -> pass : ["line
break"]
fail28.json -> pass : ["line
break"]


However, this is strictly data. I think current json-parse is enough to use.



PS. A strange things, fail18.json also passes on JSONLint (http://jsonlint.com/">http://jsonlint.com/).
#11
Hi.



json-parse cannot handle JSON data with inner double quote chars.


> (setf data [text]{"foo": ["bar", ""baz""]}[/text])
"{"foo": ["bar", "\"baz\""]}"
> (json-parse data)
nil
> (json-error)
("invalid JSON array format" 19)


This problem doesn't occur in previous json module.


> (module "json.lsp")
MAIN
> (json2expr data)
(("foo" ("bar" ""baz"")))


P.S. Is json module no longer available?

Documentation page is alive. but download link is 404.

http://www.newlisp.org/code/modules/json.lsp.html">//http://www.newlisp.org/code/modules/json.lsp.html
#12
newLISP and the O.S. / Substitute _CRT_fmode
March 28, 2013, 07:52:09 PM
Hi Lutz.



in nl-filesys.c:76
/*
Set binary as default file mode for Windows.
See also http://www.mingw.org/MinGWiki/index.php/binary
*/
unsigned int _CRT_fmode = _O_BINARY;

This technique cannot available because of unimplemented in MinGW64.

and URL has changed to http://oldwiki.mingw.org/index.php/binary">//http://oldwiki.mingw.org/index.php/binary.



_setmode function is available to use mingw32 and 64.


#include <stdio.h>
#include <fcntl.h>
#include <io.h>
...
int main(...) {
#if _WIN32
        _setmode(_fileno(stdin), _O_BINARY);
        _setmode(_fileno(stdout), _O_BINARY);
        _setmode(_fileno(stderr), _O_BINARY);
#endif
}

Regards.
#13
newLISP and the O.S. / kill function fow MinGW
October 08, 2012, 10:47:26 AM
Hello Lutz.



This patch is implementation 'kill' function for MinGW (Windows).

and modified 'plainProcess' and 'p_destroy' functions.


int kill(pid_t pid, int sig);

'kill' function terminates specified process by process ID.

However, second argument (int sig) will be ignored.


diff -wru newlisp-10.4.4-orig/nl-filesys.c newlisp-10.4.4/nl-filesys.c
--- newlisp-10.4.4-orig/nl-filesys.c 2012-09-14 00:00:27 +0900
+++ newlisp-10.4.4/nl-filesys.c 2012-10-05 14:34:46 +0900
@@ -72,6 +72,8 @@
 #define pclose _pclose
 #define pipe _pipe
 
+int kill(pid_t pid, int sig);
+
 /*
 Set binary as default file mode for Windows.
 See also http://www.mingw.org/MinGWiki/index.php/binary
@@ -1142,22 +1144,25 @@
 {
 char * cPtr;
 char * argv[16];
-int idx;
+HANDLE hProc;
+DWORD pid;
 
 cPtr = callocMemory(len + 1);
 memcpy(cPtr, command, len + 1);
 
 init_argv(cPtr, argv);
 
-idx = spawnvp(P_NOWAIT, argv[0], (const char * const *)argv);
+hProc = (HANDLE)_spawnvp(P_NOWAIT, argv[0], (const char * const *)argv);
 
 free(cPtr);
-if(idx == -1) return(nilCell);
+if (hProc == INVALID_HANDLE_VALUE) return nilCell;
 
-return(stuffInteger(idx));
+pid = GetProcessId(hProc);
+CloseHandle(hProc);
+return stuffInteger(pid);
 }
 
-
+#if 0
 CELL * p_destroyProcess(CELL * params)
 {
 UINT pid;
@@ -1171,7 +1176,7 @@
 
 return(trueCell);
 }
-
+#endif
 
 #else /* not WIN_32 */
 
@@ -1843,23 +1848,6 @@
 /* --------------------------- end Cilk ------------------------------------- */
 
 
-CELL * p_destroyProcess(CELL * params)
-{
-UINT pid;
-UINT sig;
-
-params = getInteger(params, &pid);
-if(params != nilCell)  
-    getInteger(params, &sig);
-else
-    sig = 9;
-
-if(kill(pid, sig) != 0)
-    return(nilCell);
-
-return(trueCell);
-}
-
 extern SYMBOL * symHandler[];
 
 CELL * p_waitpid(CELL * params)
@@ -1889,6 +1877,23 @@
 
 #endif
 
+CELL * p_destroyProcess(CELL * params)
+{
+UINT pid;
+UINT sig;
+
+params = getInteger(params, &pid);
+if(params != nilCell)  
+    getInteger(params, &sig);
+else
+    sig = 9;
+
+if(kill(pid, sig) != 0)
+    return(nilCell);
+
+return(trueCell);
+}
+
 /* ------------------------------ semaphores --------------------------------- */
 
 #ifdef WIN_32
diff -wru newlisp-10.4.4-orig/win32-util.c newlisp-10.4.4/win32-util.c
--- newlisp-10.4.4-orig/win32-util.c 2012-09-14 00:00:27 +0900
+++ newlisp-10.4.4/win32-util.c 2012-10-05 14:29:12 +0900
@@ -25,6 +25,19 @@
 #include <windows.h>
 #include <io.h>
 
+/* kill for MinGW */
+int kill(pid_t pid, int sig)
+{
+  int ret;
+  HANDLE h;
+  /* if (pid > 0 && sig == SIGTERM) { */
+  h = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
+  if (h == NULL) return -1;
+  ret = TerminateProcess(h, 0) ? 0 : -1;
+  CloseHandle(h);
+  /* } */
+  return ret;
+}
 
 /*
 typedef struct _PROCESS_INFORMATION { // pi  


Example:
$ newlisp
> (setq pid (process "notepad.exe"))
5156
> (destroy pid) ; kll process
true
> (destroy pid) ; already killed
nil
> (destroy (sys-info -3)) ; kill your own process
$
#14
newLISP and the O.S. / [text] tag and EOF
June 02, 2012, 02:38:28 AM
Hi Lutz.



This file is a script which assign a string into str. but missing [/text] tag.


;; foo.lsp
(setq str [text]
AAA
BBB
CCC
EOF


When execute this script, becomes the error by lack of memory.


$ newlisp foo.lsp

ERR: not enough memory


I want to work as follows:


$ newlisp foo.lsp

ERR: missing end of text [/text]


Regards.
#15
newLISP and the O.S. / Patch for xmlrpc module
March 26, 2012, 11:05:15 AM
Hello Lutz.

This patch is for correcting XML-RPC module (xmlrpc.cgi and xmlrpc-client.lsp).



example/xmlrpc.cgi:
--- newlisp-10.4.0/examples/xmlrpc.cgi.orig 2012-03-07 02:42:20.000000000 +0900
+++ newlisp-10.4.0/examples/xmlrpc.cgi 2012-03-26 14:40:35.000000000 +0900
@@ -128,7 +128,7 @@
     
 
 (define (system.methodHelp params, methodName)
-    (set 'methodName (nth (params 0 1 1 1 1)))
+    (set 'methodName (params 0 1 1 1 1))
     (case methodName
         ("system.listMethods" (format normal-response "Lists all methods implemented."))
         ("system.methodHelp" (format normal-response "Documents a method."))
@@ -138,7 +138,7 @@
 )
 
 (define (system.methodSignature params)
-    (set 'methodName (nth (params 0 1 1 1 1)))
+    (set 'methodName (params 0 1 1 1 1))
     (case methodName
         ("system.listMethods" (format normal-response
 "<array>

module/xmlrpc-client.lsp:
--- newlisp-10.4.0/modules/xmlrpc-client.lsp.orig 2012-02-14 23:51:11.000000000 +0900
+++ newlisp-10.4.0/modules/xmlrpc-client.lsp 2012-03-26 14:09:38.466104400 +0900
@@ -114,6 +114,8 @@
 ;
 (define (get-value expr)
     (if (empty? expr) nil
+
+        (list? (expr 1))
         (case (expr 1 0)
             ("i4" (int (expr 1 1)))
             ("int" (int (expr 1 1)))
@@ -126,7 +128,10 @@
                          (get-array (rest (expr 1 1)))) )
             ("struct" (get-struct (rest (expr 1))))
             ("string" (expr 1 1))
-            (true (expr 1)))) )
+            (true (expr 1)))
+
+        true (string (expr 1))       ; If no type is indicated, the type is string.
+      ))
 
 ; get contents from expr = ((value ...) (value ...) ...)
 ;


Now, http://www.newlisp.org/downloads/newlisp_manual.html#XML">XML-RPC sample will works well.
> (module "xmlrpc-client.lsp")
MAIN
> (XMLRPC:system.methodSignature "http://example.com/xmlrpc.cgi" "newLISP.evalString")
(("base64" "base64"))
; A past return value is (("m30" "m30"))
#16
newLISP and the O.S. / ostype from sys-info
March 25, 2012, 11:36:45 AM
According to document, '(sys-info 9)' returns a following value:
QuoteOperating system constant:

linux=1, bsd=2, osx=3, solaris=4, cygwin=5, win32=6, os/2=7, tru64unix=9

But in newlisp.c is written like this:
#ifdef CYGWIN
int opsys = 8;
#endif

#ifdef TRU64
int opsys = 9;
#endif

#ifdef AIX
int opsys = 10;
#endif


It seems that values in the case of CYGWIN are different. and value of AIX missing from document.

Which is rgitht?
#17
newLISP and the O.S. / IPv6 headers in Cygwin
October 18, 2011, 05:56:30 AM
Hi Lutz.



According to cygwin mailing list, IPv6 headers don't exist in Cygwin.



http://cygwin.com/ml/cygwin/2011-03/msg00459.html">http://cygwin.com/ml/cygwin/2011-03/msg00459.html
QuoteOn Mar 15 22:07, Olivier Lefevre wrote:

> I am trying to compile mtr-0.80. configure completed without

> errors but make puts:

>

> net.h:25:25: error: netinet/ip6.h: No such file or directory

> net.h:26:27: error: netinet/icmp6.h: No such file or directory

>

> I couldn't find what additional packages I should download to

> get IPv6 headers (which I assume are IPv6).



These headers don't exist in Cygwin.  IPv6 works, but only if

you use the standard headers like netinet/in.h or netinet/ip.h.


However, newLISP can be compiled by copying icmp6.h header file from other OS.

# Of course, When using raw packet in Windows 7 user application is required administrator privileges.


--- nl-sock.c.orig Tue Jun 14 12:52:46 2011
+++ nl-sock.c Tue Jun 14 12:51:30 2011
@@ -60,6 +60,7 @@
 #endif /* end UNIX */
 
 #ifdef CYGWIN
+#include <netinet/icmp6.h>
 #define ICMP_ECHO 8


If there are no GPL licensing issues, I will recommend put in the IPv6 header in newLISP package.
#18
Hi.



When url-encoded string to "get-url" is passed, the debug output is not correctly.

It happens because passing the url-encoded string directly to the varPrintf function argument.


newLISP v.10.3.0 on BSD IPv4/6 UTF-8, execute 'newlisp -h' for more info.

> (get-url "http://localhost/%E6%97%A5%E6%9C%AC%E8%AA%9E.txt" "header debug")
HEAD /2.371515E-3226                                                                                                %A5-1.239576E-016   ・戟・0X1.45100BFBFB98CP-380C-1.246019E-0180X1.84038918P-1041A5.691031E-270.txt HTTP/1.1
Host: localhost
User-Agent: newLISP v10300
Connection: close

"Date: Sun, 19 Jun 2011 15:40:05 GMTrnServer: Apache/1.3.41 (Unix) mod_tsunami/3.0 mod_gzip/1.3.26.1arnLast-Modified: Wed, 22 Oct 2003 02:25:04 GMTrnETag: "35e800b-1de-3f95ea80;4d229c99"rnAccept-Ranges: bytesrnContent-Length: 478rnConnection: closernContent-Type: text/htmlrnrn"
>


Patch file is here:


--- nl-web.c.orig 2011-06-20 00:19:52.000000000 +0900
+++ nl-web.c 2011-06-20 00:22:55.000000000 +0900
@@ -182,7 +182,7 @@
 vasprintf(&buffer, format, argptr);
 
 result = send(sock, buffer, strlen(buffer), NO_FLAGS_SET);
-if(debug) varPrintf(OUT_CONSOLE, buffer);
+if(debug) varPrintf(OUT_CONSOLE, "%s", buffer);
 
 freeMemory(buffer);
 va_end(argptr);
@@ -446,14 +446,14 @@
 
  if(transfer(sock, putPostStr, size) == SOCKET_ERROR)
  return(webError(ERROR_TRANSFER));
- if(debugFlag) varPrintf(OUT_CONSOLE, putPostStr);
+ if(debugFlag) varPrintf(OUT_CONSOLE, "%s", putPostStr);
  }
 else if(type == HTTP_POST)
  {
  sendf(sock, debugFlag, "Content-type: %srnContent-length: %drnrn", contentType, size);
  if(transfer(sock, putPostStr, size) == SOCKET_ERROR)
  return(webError(ERROR_TRANSFER));
- if(debugFlag) varPrintf(OUT_CONSOLE, putPostStr);
+ if(debugFlag) varPrintf(OUT_CONSOLE, "%s", putPostStr);
  }
 else /* HTTP_GET, HTTP_DELETE */
  sendf(sock, debugFlag, "rn");
@@ -1023,7 +1023,7 @@
  close(getSocket(IOchannel));
  }
 else
- varPrintf(OUT_CONSOLE, content);
+ varPrintf(OUT_CONSOLE, "%s", content);
 return;
 #endif
 #ifdef DEBUGHTTP
#19
$ ./newlisp
newLISP v.10.3.0 on Linux IPv4/6 UTF-8, execute 'newlisp -h' for more info.

>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ... (Large strings MAX_COMMAND_LINE or more)
*** buffer overflow detected ***: ./newlisp terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x50)[0x1f2390]
/lib/tls/i686/cmov/libc.so.6(+0xe12ca)[0x1f12ca]
./newlisp[0x8055870]
./newlisp[0x8055f52]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x126bd6]
./newlisp[0x804a921]
======= Memory map: ========
...


Patch is below:


$ diff -u newlisp_orig.c newlisp.c
--- newlisp_orig.c 2011-02-25 09:48:10.000000000 +0900
+++ newlisp.c 2011-02-25 09:48:47.000000000 +0900
@@ -1059,12 +1059,15 @@
  openStrStream(cmdStream, 1024, TRUE);
  for(;;)
  {
+                memset(buff, '', MAX_COMMAND_LINE); /* initialize buffer */
  if(isTTY)
  {
  cmd = getCommandLine(TRUE);
- strncpy(buff, cmd, MAX_COMMAND_LINE -1);
 #ifdef READLINE
+ strncpy(buff, cmd, MAX_COMMAND_LINE -2);
  strlcat(buff, "n", 1);
+#else
+                        strncpy(buff, cmd, MAX_COMMAND_LINE -1);
 #endif
  free(cmd);
  }
#20
Hello, Lutz.



The problem that does not correctly convert float to integer was found.


newLISP v.10.3.0 on Linux IPv4/6 UTF-8, execute 'newlisp -h' for more info.

> (setq x (exp (gammaln 6)))
120
> (float? x)
true
> (int x)
119
> (bits x)
"1110111"        ; (int "1110111" 0 2) is 119
> (bits 120.0)
"1111000"
> (dump x)
(147342976 387 147335024 -9 1079902207)