Bug 14237 - bug & patch: attempt to open a gzcon on a writable textConnection crashes R
bug & patch: attempt to open a gzcon on a writable textConnection crashes R
Status: RESOLVED FIXED
Product: R
Classification: Unclassified
Component: I/O
R 2.10.1 patched
All All
: P5 minor
Assigned To: R-core
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-03-23 18:37 UTC by John Brzustowski
Modified: 2010-04-09 20:15 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Brzustowski 2010-03-23 18:37:25 UTC
R version 2.10.1 Patched (2010-03-20 r51369)
...
> f<-gzcon(textConnection("x", "w"))
Error in gzcon(textConnection("x", open = "w")) : 
  'write' not enabled for this connection
> getAllConnections()
[1] 0 1 2 3
> getConnection(3)

 *** caught segfault ***
address (nil), cause 'memory not mapped'

Traceback:
 1: getConnection(3)
================================================================================
Diagnosis: the "write" function pointer of a textConnection is set to null_write(), and so gzcon's call to init_con() causes a non-local exit that
leaves the original connection in an inconsistent state.

Proposed (lazy) solution: since embedded NULs are no longer allowed in character variables, gzcon() should not permit a writable textConnection for its "object" parameter.

Patch:
diff -r -c R-patched/src/library/base/man/gzcon.Rd R-patched-fixed/src/library/base/man/gzcon.Rd
*** R-patched/src/library/base/man/gzcon.Rd	2010-03-17 10:43:08.000000000 -0400
--- R-patched-fixed/src/library/base/man/gzcon.Rd	2010-03-23 13:03:14.000000000 -0400
***************
*** 29,35 ****
    Reading from a connection which does not supply a \code{gzip} magic
    header is equivalent to reading from the original connection if
    \code{allowNonCompressed} is true, otherwise an error.
!  
    The original connection becomes unusable: any object pointing to it will
    now refer to the modified connection.
  }
--- 29,39 ----
    Reading from a connection which does not supply a \code{gzip} magic
    header is equivalent to reading from the original connection if
    \code{allowNonCompressed} is true, otherwise an error.
!   
!   Compressed output will contain embedded NUL bytes, and so \code{con}
!   is not permitted to be a \code{textConnection} opened with \code{open="w"}.
!   Use a writable \code{rawConnection} to compress data into a variable.
!  
    The original connection becomes unusable: any object pointing to it will
    now refer to the modified connection.
  }
diff -r -c R-patched/src/main/connections.c R-patched-fixed/src/main/connections.c
*** R-patched/src/main/connections.c	2010-03-17 10:43:21.000000000 -0400
--- R-patched-fixed/src/main/connections.c	2010-03-23 13:13:57.000000000 -0400
***************
*** 4988,4993 ****
--- 4988,4996 ----
         (strcmp(m, "r") == 0 || strcmp(m, "w") == 0))
  	warning(_("using a text-mode 'file' connection may not work correctly"));
  
+     if(strcmp(incon->class, "textConnection") == 0 && strcmp(m, "w") == 0)
+ 	error(_("cannot create a gzcon connection from a writable textConnection; use a rawConnection instead"));
+ 
      new = (Rconnection) malloc(sizeof(struct Rconn));
      if(!new) error(_("allocation of 'gzcon' connection failed"));
      new->class = (char *) malloc(strlen("gzcon") + 1);
Comment 1 Brian Ripley 2010-04-08 18:32:24 UTC
This is silly: gzip is binary, textConnections are text.
Comment 2 Brian Ripley 2010-04-08 18:34:15 UTC
gzip is binary, textConnections are text
Comment 3 Martin Maechler 2010-04-09 20:15:09 UTC
Even though it's silly use, a misuseR should not be able to evoke a seg.fault so easily. So, I'm fixing it all the same.

Martin