[GRASS-dev] Python script test

Michael Barton michael.barton at asu.edu
Mon Jul 21 13:14:39 EDT 2008


On Jul 21, 2008, at 2:17 AM, Glynn Clements wrote:

>
> Michael Barton wrote:
>
>> Init.sh is not updating PYTHONPATH on my Mac for some reason. I've
>> looked at the code and it seems fine. I DO have a PYTHONPATH. So I'm
>> not sure why it is not updating it. If I change it manually, by  
>> simply
>> pasting your code (export PYTHONPATH="$GISBASE/etc/python:
>> $PYTHONPATH") into the GRASS prompt, PYTHONPATH IS modified
>> appropriately and r_in_aster.py works fine with the new grass.py
>> library.
>
> I suspect that /etc/profile resets PYTHONPATH. Init.sh creates a
> .bashrc script in the mapset directory (which, at the point that the
> session shell is started, is $HOME), and that script sources
> /etc/profile.
>

That's it. PYTHONPATH is set in my .profile. So it overwrites whatever  
GRASS has set. I can fix this for me, but yours fixes this more  
generally.

Michael

> That's almost certainly bogus. /etc/profile is only meant to be
> sourced by login shells, not by subshells, largely for reasons such as
> this. I have fixed this in SVN trunk.
>
> AFAICT, you can get around this by setting the environment variable
> PROFILEREAD (to anything) before starting GRASS (this looks backwards;
> I would expect such a variable to cause /etc/profile to be read, not
> inhibit it).
>
> Really, Init.sh does way too much. Over the years, it has accumulated
> all manner of "neat tricks" (where "neat" is from the perspective of
> whoever decided to add them).
>
>> The only odd difference that I notice is that the source file is
>> init.sh and the startup in the binary is Init.sh. This is especially
>> odd since case doesn't matter when running programs on a Mac. I'm
>> copying William Kyngesbury in case he has some insight.
>
> Init.sh is generated from init.sh by substitution:
>
> 	$(ETC)/Init.sh: init.sh
> 		rm -f $@
> 		$(SHELL) -c "sed \
> 		-e \"s#GRASS_VERSION_NUMBER#$(GRASS_VERSION_NUMBER)#\" \
> 		-e \"s#GRASS_VERSION_DATE#$(GRASS_VERSION_DATE)#\" \
> 		-e \"s#GRASS_VERSION_UPDATE_PKG#$(GRASS_VERSION_UPDATE)#\" \
> 		-e \"s#LD_LIBRARY_PATH_VAR#$(LD_LIBRARY_PATH_VAR)#g\" \
> 		-e \"s#PERL_COMMAND#$(PERL)#\" \
> 		-e \"s#START_UP#$(START_UP)#\" \
> 		-e \"s#CONFIG_PROJSHARE#$(PROJSHARE)#\" \
> 		init.sh > $@"
> 		chmod +x $@
>
>> With respect to the tempfile question, what happens on Windows when
>> you use g.tempfile vs. Python's tempfile.TemporaryFile()? Overall, it
>> seems like the Python tempfile module is easier to work with and
>> potentially more secure.
>
> AFAICT, tempfile.TemporaryFile() won't suffice for most uses, as the
> filename may be removed as soon as it is created. More below.
>
> The main security risk is with temporary files is symlink attacks. You
> choose a temporary filename, then open the file for write, but before
> you have chance to do so, an attacker creates a symlink with the
> chosen name, pointing at some existing file, which you then end up
> overwriting.
>
> That's only a risk because temporary files are traditionally created
> in the /tmp directory, which is world-writable. If you create
> temporary files in a directory for which only you have write
> permission, it isn't a problem.
>
> When tempfile functions are described as insecure, this is the issue
> in question. The "secure" alternatives invariably open the temporary
> file for write (without truncating the file); once the file is open,
> the function re-checks whether the name refers to a file or to a
> symlink. If it's a symlink, it immediately closes the file and tries
> again.
>
> Such functions often return a descriptor or FILE* rather than a
> filename. Python's os.tmpfile() behaves like this. Unfortunately, this
> is of no use if you need to pass a filename to another program (files
> created by os.tmpfile() don't have a name, and will be automatically
> deleted when closed).
>
> os.tempnam() and os.tmpnam() both return names without creating the
> file. os.tempnam() allows the directory to be specified, so you could
> use e.g. /tmp/grass-<user>-<pid> or <mapset>/.tmp/<hostname> for the
> files. os.tmpnam() doesn't allow the directory to be specified;
> according to the documentation, the Windows implementation chooses a
> name in the root directory of the current driver, where you may not
> even have permission to create files.
>
> I hadn't looked at the tempfile module before now.
>
> TemporaryFile() and NamedTemporaryFile() produce files which may not
> have a name or which may not be able to be re-opened (i.e.
> auto-deleted when closed), so they can't be used in the general case,
> although they may be useful for scripts wanting to use temporary files
> internally (although os.tmpfile() will suffice there).
>
> mkstemp() would suffice for creating temporary files. It returns both
> the handle (which you can close) and the filename, and the file isn't
> autodeleted.
>
> mktemp() is like mkstemp() but doesn't open the file, and just returns
> a filename. This potentially suffers from symlink attackes, but that
> isn't an issue if a private directory is used.
>
> -- 
> Glynn Clements <glynn at gclements.plus.com>



More information about the grass-dev mailing list