Exemple #1
0
/* The startup code also calls this to open @-files. */
int
lib_file_open(gs_file_path_ptr  lib_path, const gs_memory_t *mem, i_ctx_t *i_ctx_p,
                       const char *fname, uint flen, char *buffer, int blen, uint *pclen, ref *pfile)
{   /* i_ctx_p is NULL running arg (@) files.
     * lib_path and mem are never NULL
     */
    bool starting_arg_file = (i_ctx_p == NULL) ? true : i_ctx_p->starting_arg_file;
    bool search_with_no_combine = false;
    bool search_with_combine = false;
    char fmode[4] = { 'r', 0, 0, 0 };           /* room for binary suffix */
    gx_io_device *iodev = iodev_default(mem);
    gs_main_instance *minst = get_minst_from_memory(mem);
    int code;

    /* when starting arg files (@ files) iodev_default is not yet set */
    if (iodev == 0)
        iodev = (gx_io_device *)gx_io_device_table[0];

    strcat(fmode, gp_fmode_binary_suffix);
    if (gp_file_name_is_absolute(fname, flen)) {
       search_with_no_combine = true;
       search_with_combine = false;
    } else {
       search_with_no_combine = starting_arg_file;
       search_with_combine = true;
    }
    if (minst->search_here_first) {
      if (search_with_no_combine) {
        code = lib_file_open_search_with_no_combine(lib_path, mem, i_ctx_p,
                                                    fname, flen, buffer, blen, pclen, pfile,
                                                    iodev, starting_arg_file, fmode);
        if (code <= 0) /* +ve means continue continue */
          return code;
      }
      if (search_with_combine) {
        code = lib_file_open_search_with_combine(lib_path, mem, i_ctx_p,
                                                 fname, flen, buffer, blen, pclen, pfile,
                                                 iodev, starting_arg_file, fmode);
        if (code <= 0) /* +ve means continue searching */
          return code;
      }
    } else {
      if (search_with_combine) {
        code = lib_file_open_search_with_combine(lib_path, mem, i_ctx_p,
                                                 fname, flen, buffer, blen, pclen, pfile,
                                                 iodev, starting_arg_file, fmode);
        if (code <= 0) /* +ve means continue searching */
          return code;
      }
      if (search_with_no_combine) {
        code = lib_file_open_search_with_no_combine(lib_path, mem, i_ctx_p,
                                                    fname, flen, buffer, blen, pclen, pfile,
                                                    iodev, starting_arg_file, fmode);
        if (code <= 0) /* +ve means continue searching */
          return code;
      }
    }
    return_error(e_undefinedfilename);
}
Exemple #2
0
/* The startup code also calls this to open @-files. */
int
lib_file_open(gs_file_path_ptr  lib_path, const gs_memory_t *mem, i_ctx_t *i_ctx_p,      
		       const char *fname, uint flen, char *buffer, int blen, uint *pclen, ref *pfile)
{   /* i_ctx_p is NULL running arg (@) files. 
     * lib_path and mem are never NULL 
     */
    bool starting_arg_file = (i_ctx_p == NULL) ? true : i_ctx_p->starting_arg_file;
    bool search_with_no_combine = false;
    bool search_with_combine = false;
    char fmode[4] = { 'r', 0, 0, 0 };		/* room for binary suffix */
    stream *s;
    gx_io_device *iodev = iodev_default;

    /* when starting arg files (@ files) iodev_default is not yet set */
    if (iodev == 0)
        iodev = (gx_io_device *)gx_io_device_table[0];
    
    strcat(fmode, gp_fmode_binary_suffix);
    if (gp_file_name_is_absolute(fname, flen)) {
       search_with_no_combine = true;
       search_with_combine = false;
    } else {
       search_with_no_combine = starting_arg_file;
       search_with_combine = true;
    }
    if (search_with_no_combine) {
	uint blen1 = blen;

	if (gp_file_name_reduce(fname, flen, buffer, &blen1) != gp_combine_success)
	    goto skip;
	if (iodev_os_open_file(iodev, (const char *)buffer, blen1,
				(const char *)fmode, &s, (gs_memory_t *)mem) == 0) {
	    if (starting_arg_file ||
			check_file_permissions_aux(i_ctx_p, buffer, blen1) >= 0) {
		*pclen = blen1;
		make_stream_file(pfile, s, "r");
		return 0;
	    }
	    sclose(s);
	    return_error(e_invalidfileaccess);
	}
	skip:;
    } 
    if (search_with_combine) {
	const gs_file_path *pfpath = lib_path;
	uint pi;

	for (pi = 0; pi < r_size(&pfpath->list); ++pi) {
	    const ref *prdir = pfpath->list.value.refs + pi;
	    const char *pstr = (const char *)prdir->value.const_bytes;
	    uint plen = r_size(prdir), blen1 = blen;
    	    gs_parsed_file_name_t pname;
	    gp_file_name_combine_result r;

	    /* We need to concatenate and parse the file name here
	     * if this path has a %device% prefix.		*/
	    if (pstr[0] == '%') {
		int code;

		/* We concatenate directly since gp_file_name_combine_*
		 * rules are not correct for other devices such as %rom% */
		gs_parse_file_name(&pname, pstr, plen);
		memcpy(buffer, pname.fname, pname.len);
		memcpy(buffer+pname.len, fname, flen);
		code = pname.iodev->procs.open_file(pname.iodev, buffer, pname.len + flen, fmode,
					      &s, (gs_memory_t *)mem);
		if (code < 0)
		    continue;
		make_stream_file(pfile, s, "r");
		/* fill in the buffer with the device concatenated */
		memcpy(buffer, pstr, plen);
		memcpy(buffer+plen, fname, flen);
		*pclen = plen + flen;
		return 0;
	    } else {
		r = gp_file_name_combine(pstr, plen, 
			fname, flen, false, buffer, &blen1);
		if (r != gp_combine_success)
		    continue;
		if (iodev_os_open_file(iodev, (const char *)buffer, blen1, (const char *)fmode,
					&s, (gs_memory_t *)mem) == 0) {
		    if (starting_arg_file ||
			check_file_permissions_aux(i_ctx_p, buffer, blen1) >= 0) {
			*pclen = blen1;
			make_stream_file(pfile, s, "r");
			return 0;
		    }
		    sclose(s);
		    return_error(e_invalidfileaccess);
		}
	    }
	}
    }
    return_error(e_undefinedfilename);
}
Exemple #3
0
/* <prefix|null> <access_string> .tempfile <name_string> <file> */
static int
ztempfile(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    const char *pstr;
    char fmode[4];
    int code = parse_file_access_string(op, fmode);
    char prefix[gp_file_name_sizeof];
    char fname[gp_file_name_sizeof];
    uint fnlen;
    FILE *sfile;
    stream *s;
    byte *buf;

    if (code < 0)
	return code;
    strcat(fmode, gp_fmode_binary_suffix);
    if (r_has_type(op - 1, t_null))
	pstr = gp_scratch_file_name_prefix;
    else {
	uint psize;

	check_read_type(op[-1], t_string);
	psize = r_size(op - 1);
	if (psize >= gp_file_name_sizeof)
	    return_error(e_rangecheck);
	memcpy(prefix, op[-1].value.const_bytes, psize);
	prefix[psize] = 0;
	pstr = prefix;
    }

    if (gp_file_name_is_absolute(pstr, strlen(pstr))) {
	if (check_file_permissions(i_ctx_p, pstr, strlen(pstr),
				   "PermitFileWriting") < 0) {
	    return_error(e_invalidfileaccess);
	}
    } else if (!prefix_is_simple(pstr)) {
	return_error(e_invalidfileaccess);
    }

    s = file_alloc_stream(imemory, "ztempfile(stream)");
    if (s == 0)
	return_error(e_VMerror);
    buf = gs_alloc_bytes(imemory, file_default_buffer_size,
			 "ztempfile(buffer)");
    if (buf == 0)
	return_error(e_VMerror);
    sfile = gp_open_scratch_file(pstr, fname, fmode);
    if (sfile == 0) {
	gs_free_object(imemory, buf, "ztempfile(buffer)");
	return_error(e_invalidfileaccess);
    }
    fnlen = strlen(fname);
    file_init_stream(s, sfile, fmode, buf, file_default_buffer_size);
    code = ssetfilename(s, (const unsigned char*) fname, fnlen);
    if (code < 0) {
	sclose(s);
	iodev_default->procs.delete_file(iodev_default, fname);
	return_error(e_VMerror);
    }
    make_const_string(op - 1, a_readonly | icurrent_space, fnlen,
		      s->file_name.data);
    make_stream_file(op, s, fmode);
    return code;
}
Exemple #4
0
/* strings of the permitgroup array. */
static int
check_file_permissions_reduced(i_ctx_t *i_ctx_p, const char *fname, int len,
			const char *permitgroup)
{
    long i;
    ref *permitlist = NULL;
    /* an empty string (first character == 0) if '\' character is */
    /* recognized as a file name separator as on DOS & Windows	  */
    const char *win_sep2 = "\\";
    bool use_windows_pathsep = (gs_file_name_check_separator(win_sep2, 1, win_sep2) == 1);
    uint plen = gp_file_name_parents(fname, len);

    /* Assuming a reduced file name. */

    if (dict_find_string(&(i_ctx_p->userparams), permitgroup, &permitlist) <= 0)
        return 0;	/* if Permissions not found, just allow access */

    for (i=0; i<r_size(permitlist); i++) {
        ref permitstring;
	const string_match_params win_filename_params = {
		'*', '?', '\\', true, true	/* ignore case & '/' == '\\' */
	};
	const byte *permstr;
	uint permlen;
	int cwd_len = 0;

	if (array_get(imemory, permitlist, i, &permitstring) < 0 ||
	    r_type(&permitstring) != t_string 
	   )    
	    break;	/* any problem, just fail */
	permstr = permitstring.value.bytes;
	permlen = r_size(&permitstring);
	/* 
	 * Check if any file name is permitted with "*".
	 */
	if (permlen == 1 && permstr[0] == '*')
	    return 0;		/* success */
	/* 
	 * If the filename starts with parent references, 
	 * the permission element must start with same number of parent references.
	 */
	if (plen != 0 && plen != gp_file_name_parents((const char *)permstr, permlen))
	    continue;
	cwd_len = gp_file_name_cwds((const char *)permstr, permlen);
	/*
	 * If the permission starts with "./", absolute paths
	 * are not permitted.
	 */
	if (cwd_len > 0 && gp_file_name_is_absolute(fname, len))
	    continue;
	/*
	 * If the permission starts with "./", relative paths
	 * with no "./" are allowed as well as with "./".
	 * 'fname' has no "./" because it is reduced.
	 */
        if (string_match( (const unsigned char*) fname, len,
			  permstr + cwd_len, permlen - cwd_len, 
		use_windows_pathsep ? &win_filename_params : NULL))
	    return 0;		/* success */
    }
    /* not found */
    return e_invalidfileaccess;
}
Exemple #5
0
/* Write the actual file name at fname. */
static FILE *
gp_open_scratch_file_generic(const gs_memory_t *mem,
                             const char        *prefix,
                                   char         fname[gp_file_name_sizeof],
                             const char        *mode,
                                   bool         b64)
{       /* The -8 is for XXXXXX plus a possible final / and -. */
    int prefix_length = strlen(prefix);
    int len = gp_file_name_sizeof - prefix_length - 8;
    FILE *fp;

    if (gp_file_name_is_absolute(prefix, prefix_length))
        *fname = 0;
    else if (gp_gettmpdir(fname, &len) != 0)
        strcpy(fname, "/tmp/");
    else {
        if (strlen(fname) != 0 && fname[strlen(fname) - 1] != '/')
            strcat(fname, "/");
    }
    if (strlen(fname) + prefix_length + 8 >= gp_file_name_sizeof)
        return 0;               /* file name too long */
    strcat(fname, prefix);
    /* Prevent trailing X's in path from being converted by mktemp. */
    if (*fname != 0 && fname[strlen(fname) - 1] == 'X')
        strcat(fname, "-");
    strcat(fname, "XXXXXX");

#ifdef HAVE_MKSTEMP
    {
        int file;
        char ofname[gp_file_name_sizeof];

        /* save the old filename template in case mkstemp fails */
        memcpy(ofname, fname, gp_file_name_sizeof);
#ifdef HAVE_MKSTEMP64
        if (b64)
            file = mkstemp64(fname);
        else
            file = mkstemp(fname);
#else
        file = mkstemp(fname);
#endif
        if (file < -1) {
            emprintf1(mem, "**** Could not open temporary file %s\n", ofname);
            return NULL;
        }
#if defined(O_LARGEFILE) && defined(__hpux)
        if (b64)
            fcntl(file, F_SETFD, fcntl(file, F_GETFD) | O_LARGEFILE);
#else
        /* Fixme : what to do with b64 and 32-bit mkstemp? Unimplemented. */
#endif

        fp = fdopen(file, mode);
        if (fp == NULL)
            close(file);
    }
#else
    mktemp(fname);
    fp = (b64 ? gp_fopentemp : gp_fopentemp_64)(fname, mode);
#endif
    if (fp == NULL)
        emprintf1(mem, "**** Could not open temporary file %s\n", fname);
    return fp;
}
/* Write the actual file name at fname. */
FILE *
gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
{
    UINT n;
    DWORD l;
    HANDLE hfile = INVALID_HANDLE_VALUE;
    int fd = -1;
    FILE *f = NULL;
    char sTempDir[_MAX_PATH];
    char sTempFileName[_MAX_PATH];

    memset(fname, 0, gp_file_name_sizeof);
    if (!gp_file_name_is_absolute(prefix, strlen(prefix))) {
	int plen = sizeof(sTempDir);

	if (gp_gettmpdir(sTempDir, &plen) != 0)
	    l = GetTempPath(sizeof(sTempDir), sTempDir);
	else
	    l = strlen(sTempDir);
    } else {
	strncpy(sTempDir, prefix, sizeof(sTempDir));
	prefix = "";
	l = strlen(sTempDir);
    }
    /* Fix the trailing terminator so GetTempFileName doesn't get confused */
    if (sTempDir[l-1] == '/')
	sTempDir[l-1] = '\\';		/* What Windoze prefers */

    if (l <= sizeof(sTempDir)) {
	n = GetTempFileName(sTempDir, prefix, 0, sTempFileName);
	if (n == 0) {
	    /* If 'prefix' is not a directory, it is a path prefix. */
	    int l = strlen(sTempDir), i;

	    for (i = l - 1; i > 0; i--) {
		uint slen = gs_file_name_check_separator(sTempDir + i, l, sTempDir + l);

		if (slen > 0) {
		    sTempDir[i] = 0;   
		    i += slen;
		    break;
		}
	    }
	    if (i > 0)
		n = GetTempFileName(sTempDir, sTempDir + i, 0, sTempFileName);
	}
	if (n != 0) {
	    hfile = CreateFile(sTempFileName, 
		GENERIC_READ | GENERIC_WRITE | DELETE,
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL /* | FILE_FLAG_DELETE_ON_CLOSE */, 
		NULL);
	    /*
	     * Can't apply FILE_FLAG_DELETE_ON_CLOSE due to 
	     * the logics of clist_fclose. Also note that
	     * gdev_prn_render_pages requires multiple temporary files
	     * to exist simultaneousely, so that keeping all them opened
	     * may exceed available CRTL file handles.
	     */
	}
    }
    if (hfile != INVALID_HANDLE_VALUE) {
	/* Associate a C file handle with an OS file handle. */
	fd = _open_osfhandle((long)hfile, 0);
	if (fd == -1)
	    CloseHandle(hfile);
	else {
	    /* Associate a C file stream with C file handle. */
	    f = fdopen(fd, mode);
	    if (f == NULL)
		_close(fd);
	}
    }
    if (f != NULL) {
	if ((strlen(sTempFileName) < gp_file_name_sizeof))
	    strncpy(fname, sTempFileName, gp_file_name_sizeof - 1);
	else {
	    /* The file name is too long. */
	    fclose(f);
	    f = NULL;
	}
    }
    if (f == NULL)
	eprintf1("**** Could not open temporary file '%s'\n", fname);
    return f;
}