When performing a reverse DVI search and the tmpdir is a symlink, the

DVI viewer passes back the resolved path, such that the search fails,
as internally LyX uses the unresolved path.
This patch fixes this bug by using the new method FileName::realPath
which resolves a path by getting rid of any '.', '..', or symlink
path components.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_6_X@29504 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Enrico Forestieri 2009-05-02 21:51:06 +00:00
parent cf9da27ef4
commit 081b58b672
16 changed files with 157 additions and 10 deletions

View File

@ -112,6 +112,8 @@ LYX_ADD_INC_DIR(CPPFLAGS,$dir/include)
### These are needed in windows
AC_CHECK_LIB(shlwapi, main, [LIBSHLWAPI=-lshlwapi])
AC_SUBST(LIBSHLWAPI)
AC_CHECK_LIB(psapi, main, [LIBPSAPI=-lpsapi])
AC_SUBST(LIBPSAPI)
AC_CHECK_LIB(gdi32, main)
AC_ARG_WITH(aiksaurus,

View File

@ -69,7 +69,7 @@ target_link_libraries(support boost_signals ${QT_QTCORE_LIBRARY} ${ZLIB_LIBRARY}
if(APPLE)
target_link_libraries(support "objc" "-framework Appkit" "-framework CoreFoundation")
elseif(WIN32)
target_link_libraries(support shlwapi)
target_link_libraries(support shlwapi psapi)
endif()
project_source_group("${GROUP_CODE}" support_sources support_headers)

View File

@ -46,7 +46,7 @@ target_link_libraries(${_tex2lyx}
${ICONV_LIBRARY})
if(WIN32)
target_link_libraries(${_tex2lyx} shlwapi ole32)
target_link_libraries(${_tex2lyx} shlwapi ole32 psapi)
endif()
if(APPLE)

View File

@ -1218,9 +1218,9 @@ if platform_name in ['win32', 'cygwin']:
# the final link step needs stdc++ to succeed under mingw
# FIXME: shouldn't g++ automatically link to stdc++?
if use_vc:
system_libs += ['ole32', 'shlwapi', 'shell32', 'advapi32', 'zdll']
system_libs += ['ole32', 'shlwapi', 'psapi', 'shell32', 'advapi32', 'zdll']
else:
system_libs += ['shlwapi', 'stdc++', 'z']
system_libs += ['shlwapi', 'psapi', 'stdc++', 'z']
elif platform_name == 'cygwin' and env['X11']:
system_libs += ['GL', 'Xmu', 'Xi', 'Xrender', 'Xrandr',
'Xcursor', 'Xft', 'freetype', 'fontconfig', 'Xext', 'X11', 'SM', 'ICE',

View File

@ -1150,11 +1150,17 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
is >> file_name >> row;
Buffer * buf = 0;
bool loaded = false;
if (prefixIs(file_name, package().temp_dir().absFilename()))
string const abstmp = package().temp_dir().absFilename();
string const realtmp = package().temp_dir().realPath();
if (prefixIs(file_name, abstmp) || prefixIs(file_name, realtmp)) {
// Needed by inverse dvi search. If it is a file
// in tmpdir, call the apropriated function
// in tmpdir, call the apropriated function.
// If tmpdir is a symlink, we may have the real
// path passed back, so we correct for that.
if (!prefixIs(file_name, abstmp))
file_name = subst(file_name, realtmp, abstmp);
buf = theBufferList().getBufferFromTmp(file_name);
else {
} else {
// Must replace extension of the file to be .lyx
// and get full path
FileName const s = fileSearch(string(), changeExtension(file_name, ".lyx"), "lyx");

View File

@ -19,7 +19,7 @@ EXTRA_DIST = Section.h \
paper.h \
pch.h
OTHERLIBS = $(BOOST_LIBS) $(INTLLIBS) $(MYTHES_LIBS) $(AIKSAURUS_LIBS) @LIBS@ $(SOCKET_LIBS)
OTHERLIBS = $(BOOST_LIBS) $(INTLLIBS) $(MYTHES_LIBS) $(AIKSAURUS_LIBS) @LIBS@ $(SOCKET_LIBS) $(LIBPSAPI)
noinst_LTLIBRARIES = liblyxcore.la
bin_PROGRAMS = lyx

View File

@ -12,7 +12,7 @@ AM_CPPFLAGS += -I$(srcdir)/.. $(BOOST_INCLUDES)
lyxclient_LDADD = \
$(top_builddir)/src/support/liblyxsupport.la \
$(BOOST_LIBS) $(INTLLIBS) @LIBS@ $(SOCKET_LIBS)
$(BOOST_LIBS) $(INTLLIBS) @LIBS@ $(SOCKET_LIBS) $(LIBPSAPI)
# everything below the line containing the single backslashs
# an ugly hack and needed because of the

View File

@ -194,6 +194,12 @@ string FileName::absFilename() const
}
string FileName::realPath() const
{
return os::real_path(toFilesystemEncoding());
}
void FileName::set(string const & name)
{
d->fi.setFile(toqstr(name));

View File

@ -64,6 +64,12 @@ public:
/// get the absolute file name in UTF-8 encoding
std::string absFilename() const;
/** returns an absolute pathname (whose resolution does not involve
* '.', '..', or symbolic links) in UTF-8 encoding
*/
std::string realPath() const;
/**
* Get the file name in the encoding used by the file system.
* Only use this for accessing the file, e.g. with an fstream.

View File

@ -112,6 +112,12 @@ bool canAutoOpenFile(std::string const & ext, auto_open_mode const mode = VIEW);
*/
bool autoOpenFile(std::string const & filename, auto_open_mode const mode = VIEW);
/** Resolves a path such that it does not contain '.', '..', or symbolic links.
* \warning the path must already be in the filesystem encoding.
* \returns the resolved path in utf8 encoding.
*/
std::string real_path(std::string const & path);
} // namespace os
} // namespace support
} // namespace lyx

View File

@ -26,6 +26,7 @@
#include <shellapi.h>
#include <shlwapi.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/cygwin.h>
@ -281,6 +282,14 @@ bool autoOpenFile(string const & filename, auto_open_mode const mode)
win_path.c_str(), NULL, NULL, 1)) > 32;
}
string real_path(string const & path)
{
char rpath[PATH_MAX + 1];
char * result = realpath(path.c_str(), rpath);
return FileName::fromFilesystemEncoding(result ? rpath : path).absFilename();
}
} // namespace os
} // namespace support
} // namespace lyx

View File

@ -17,6 +17,9 @@
#include "support/FileName.h"
#include "support/lstrings.h"
#include <limits.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <Carbon/Carbon.h>
#endif
@ -215,6 +218,14 @@ bool autoOpenFile(string const & filename, auto_open_mode const mode)
#endif
}
string real_path(string const & path)
{
char rpath[PATH_MAX + 1];
char * result = realpath(path.c_str(), rpath);
return FileName::fromFilesystemEncoding(result ? rpath : path).absFilename();
}
} // namespace os
} // namespace support
} // namespace lyx

View File

@ -389,6 +389,102 @@ bool autoOpenFile(string const & filename, auto_open_mode const mode)
to_local8bit(from_utf8(filename)).c_str(), NULL, NULL, 1)) > 32;
}
string real_path(string const & path)
{
// See http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx
HANDLE hpath = CreateFile(subst(path, '/', '\\').c_str(), GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hpath == INVALID_HANDLE_VALUE) {
// The file cannot be accessed.
return FileName::fromFilesystemEncoding(path).absFilename();
}
// Get the file size.
DWORD size_hi = 0;
DWORD size_lo = GetFileSize(hpath, &size_hi);
if (size_lo == 0 && size_hi == 0) {
// A zero-length file cannot be mapped.
CloseHandle(hpath);
return FileName::fromFilesystemEncoding(path).absFilename();
}
// Create a file mapping object.
HANDLE hmap = CreateFileMapping(hpath, NULL, PAGE_READONLY, 0, 1, NULL);
if (!hmap) {
CloseHandle(hpath);
return FileName::fromFilesystemEncoding(path).absFilename();
}
// Create a file mapping to get the file name.
void * pmem = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 1);
if (!pmem) {
CloseHandle(hmap);
CloseHandle(hpath);
return FileName::fromFilesystemEncoding(path).absFilename();
}
TCHAR realpath[MAX_PATH + 1];
if (!GetMappedFileName(GetCurrentProcess(), pmem, realpath, MAX_PATH)) {
UnmapViewOfFile(pmem);
CloseHandle(hmap);
CloseHandle(hpath);
return FileName::fromFilesystemEncoding(path).absFilename();
}
// Translate device name to UNC prefix or drive letters.
TCHAR tmpbuf[MAX_PATH] = TEXT("\\Device\\Mup\\");
UINT namelen = _tcslen(tmpbuf);
if (_tcsnicmp(realpath, tmpbuf, namelen) == 0) {
// UNC path
_snprintf(tmpbuf, MAX_PATH, "\\\\%s", realpath + namelen);
strncpy(realpath, tmpbuf, MAX_PATH);
realpath[MAX_PATH] = '\0';
} else if (GetLogicalDriveStrings(MAX_PATH - 1, tmpbuf)) {
// Check whether device name corresponds to some local drive.
TCHAR name[MAX_PATH];
TCHAR drive[3] = TEXT(" :");
bool found = false;
TCHAR * p = tmpbuf;
do {
// Copy the drive letter to the template string
drive[0] = *p;
// Look up each device name
if (QueryDosDevice(drive, name, MAX_PATH)) {
namelen = _tcslen(name);
if (namelen < MAX_PATH) {
found = _tcsnicmp(realpath, name, namelen) == 0;
if (found) {
// Repl. device spec with drive
TCHAR tempfile[MAX_PATH];
_snprintf(tempfile,
MAX_PATH,
"%s%s",
drive,
realpath + namelen);
strncpy(realpath,
tempfile,
MAX_PATH);
realpath[MAX_PATH] = '\0';
}
}
}
// Advance p to the next NULL character.
while (*p++) ;
} while (!found && *p);
}
UnmapViewOfFile(pmem);
CloseHandle(hmap);
CloseHandle(hpath);
string const retpath = subst(string(realpath), '\\', '/');
return FileName::fromFilesystemEncoding(retpath).absFilename();
}
} // namespace os
} // namespace support
} // namespace lyx

View File

@ -43,6 +43,8 @@
#endif
#include <windows.h>
#include <tchar.h>
#include <psapi.h>
namespace lyx {

View File

@ -66,4 +66,4 @@ tex2lyx_SOURCES = \
tex2lyx_LDADD = \
$(top_builddir)/src/support/liblyxsupport.la \
$(LIBICONV) $(BOOST_LIBS) @LIBS@
$(LIBICONV) $(BOOST_LIBS) @LIBS@ $(LIBPSAPI)

View File

@ -294,6 +294,9 @@ What's new
Frontmatter of the layout combo box.
- Hide the "Navigate->Go to Label" menuitem when disabled (bug 4124).
- Fix bug causing reverse DVI search to fail when the temporary directory
is a symbolic link.
* DOCUMENTATION AND LOCALIZATION