[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Log message problem on 1.9.5

From: pegacorn <subscriber.jp_at_gmail.com>
Date: Thu, 05 Jan 2017 00:02:59 +0900 (JST)

# This sentence is machine translated. If you can understand Japanese, please read the second half Japanese (Original).

 From: pegacorn <subscriber.jp_at_gmail.com>
 Date: Sun, 11 Dec 2016 00:05:10 +0900 (JST)
 Message-Id: <20161211.000510.247199881.subscriber.jp_at_gmail.com>
/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> If you believe in the URL displayed in the error message, the repository name is doubly percent escaped.

I debugged, but the repository name was doubly percent-escaped after all.

> I suspected changing the URL escape processing in revision 27555, but I could not find a problem.
> > Revision: 27555
> > Modified : /branches/1.9.x/src/Utils/PathUtils.cpp

Also, doubly percent-escaping is due to changes in CPathUtils::PathEscape() at revision 27555.

Before change:
  CPathUtils::PathEscape(const CStringA& path): in: file:///D:/tmp/test%20repo/Hello world/こんにちは.txt
  CPathUtils::PathEscape(const CStringA& path): out: file:///D:/tmp/test%20repo/Hello%20world/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF.txt

After change:
  CPathUtils::PathEscape(const CStringA& path): in: file:///D:/tmp/test%20repo/Hello world/こんにちは.txt
  CPathUtils::PathEscape(const CStringA& path): out: file:///D:/tmp/test%2520repo/Hello%20world/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF.txt

However, as you can see from the input URL to CPathUtils::PathEscape() above, changing CPathUtils::PathEscape() in revision 27555 only triggered this problem, and an input URL was incorrect from before.
Correctly, I think that it should be an input URL like the following.

Correct:
  CPathUtils::PathEscape(const CStringA& path): in: file:///D:/tmp/test repo/Hello world/こんにちは.txt
  CPathUtils::PathEscape(const CStringA& path): out: file:///D:/tmp/test%20repo/Hello%20world/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF.txt

An incorrect input URL is made, for example, in the following part.

 src/TortoiseProc/LogDialog/LogDlg.cpp
/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> void CLogDlg::DoDiffFromLog( INT_PTR selIndex, svn_revnum_t rev1, svn_revnum_t rev2, bool blame, bool unified, bool ignoreprops )
(snip)
> firstfile = filepath + firstfile.Trim();
> secondfile = filepath + secondfile.Trim();

The filepath is an escaped URL(file:///D:/tmp/test%20repo) of the repository.
The firstfile and the secondfile before join are an unescaped file path(/Hello world/こんにちは.txt).

There are other places where TortoiseSVN combine such URL components with different escape state.
In other words, the root cause seems to be that TortoiseSVN cannot manage the state of percent-escape of URL.
I attempted to fix it but it seemed to me that it was not easy to fix for reasons such as the wide range of effects and the explanation of the escape state is not written in the API description.

For the time being, like pine_matsu-san, it seems to be quick to change the repository name to a name that does not require percent-escape...

# As for Subversion, as described in "ext/Subversion/subversion/include/svn_dirent_uri.h"
# it seems that we always pass an escaped URL and Subversion always return an escaped URL.
# TortoiseSVN seems to be the specification that passes unescaped URL to the SVN class in the description of "src/SVN/SVN.h",
# but there is no description about the URL to return, SVN::GetURLFromPath(), SVN::GetRepositoryRootAndUUID() etc return an escaped URL.
# I think this is the cause of confusion.
#
# src/SVN/SVN.h
# /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# > * \remark Please note that all URLs passed to any of the methods of this class
# > * must not be escaped! Escaping and unescaping of URLs is done automatically.
# > * The drawback of this is that valid pathnames with sequences looking like escaped
# > * chars may not work correctly under certain circumstances.

The following is a sentence in Japanese (Original).
以下は日本語(原文)の文章です。

> エラーメッセージ中に表示されるURLを信じるなら、リポジトリ名が2重にパーセントエスケープされています。

デバッグしてみた所、やはりリポジトリ名が2重にパーセントエスケープされていました。

> リビジョン27555でのURLのエスケープ処理の変更を疑いましたが、問題は見つけられませんでした。
> > Revision: 27555
> > Modified : /branches/1.9.x/src/Utils/PathUtils.cpp

また、2重にパーセントエスケープされるようになったのは、リビジョン27555でのCPathUtils::PathEscape()の変更が原因です。

変更前:
  CPathUtils::PathEscape(const CStringA& path): in: file:///D:/tmp/test%20repo/Hello world/こんにちは.txt
  CPathUtils::PathEscape(const CStringA& path): out: file:///D:/tmp/test%20repo/Hello%20world/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF.txt

変更後:
  CPathUtils::PathEscape(const CStringA& path): in: file:///D:/tmp/test%20repo/Hello world/こんにちは.txt
  CPathUtils::PathEscape(const CStringA& path): out: file:///D:/tmp/test%2520repo/Hello%20world/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF.txt

しかし、上記のCPathUtils::PathEscape()への入力URLを見てわかるように、リビジョン27555でのCPathUtils::PathEscape()の変更は今回の問題のきっかけになっただけで、以前から入力URLが間違っていました。
正しくは、以下のような入力URLにならなければならないはずです。

正:
  CPathUtils::PathEscape(const CStringA& path): in: file:///D:/tmp/test repo/Hello world/こんにちは.txt
  CPathUtils::PathEscape(const CStringA& path): out: file:///D:/tmp/test%20repo/Hello%20world/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF.txt

この間違った入力URLを作っているのは、例えば以下の箇所です。

 src/TortoiseProc/LogDialog/LogDlg.cpp
/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> void CLogDlg::DoDiffFromLog( INT_PTR selIndex, svn_revnum_t rev1, svn_revnum_t rev2, bool blame, bool unified, bool ignoreprops )
(省略)
> firstfile = filepath + firstfile.Trim();
> secondfile = filepath + secondfile.Trim();

filepathは、リポジトリのエスケープされたURL(file:///D:/tmp/test%20repo)です。
結合前のfirstfile, secondfileは、エスケープされていないファイルパス(/Hello world/こんにちは.txt)です。

このようなエスケープ状態の事なるURLコンポーネントを結合している個所が他にもあります。
つまり、根本的な原因はTortoiseSVNがURLのパーセントエスケープの状態を管理できていない事のようです。
修正を試みましたが、影響が広範囲に渡っている事や、エスケープ状態の説明がAPIの説明に書かれていない等の理由で、私には簡単には治せそうにありませんでした。

取り敢えず、pine_matsuさんのようにリポジトリ名をパーセントエスケープが不要な名前に変更して凌ぐのが手っ取り早そうです…

# Subversionは、「ext/Subversion/subversion/include/svn_dirent_uri.h」に書かれている通り、
# 常にエスケープしたURLを渡し、常にエスケープしたURLを返すようです。
# TortoiseSVNは、「src/SVN/SVN.h」の説明ではSVNクラスにはエスケープしていないURLを渡す仕様のようですが、
# 返すURLについては説明がなく、SVN::GetURLFromPath()やSVN::GetRepositoryRootAndUUID()等はエスケープしたURLを返しています。
# これが混乱の原因だと思います。
#
# src/SVN/SVN.h
# /~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# > * \remark Please note that all URLs passed to any of the methods of this class
# > * must not be escaped! Escaping and unescaping of URLs is done automatically.
# > * The drawback of this is that valid pathnames with sequences looking like escaped
# > * chars may not work correctly under certain circumstances.

-- 
pegacorn
------------------------------------------------------
http://tortoisesvn.tigris.org/ds/viewMessage.do?dsForumId=4061&dsMessageId=3199280
To unsubscribe from this discussion, e-mail: [users-unsubscribe_at_tortoisesvn.tigris.org].
Received on 2017-01-07 02:32:13 CET

This is an archived mail posted to the TortoiseSVN Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.