tDiaryのCSRF対策の変更の影響でxyzzyのtDiary-modeから書けなくなってしまったので、本家tDiary-modeの差分(http.lとtdiary-model.l)を見ながら適当にパッチを作ってみました。一応、appendとreplaceが動くのは確認していますが、とてもいい加減です*1。
diff -uNr tdiary.orig/http.l tdiary/http.l
--- tdiary.orig/http.l 2004-02-03 02:57:44.000000000 +0900
+++ tdiary/http.l 2005-07-20 23:56:19.641082700 +0900
@@ -91,6 +91,7 @@
" HTTP/1.0\r\n"
(concat "Host: " server "\r\n")
"Connection: close\r\n"
+ "Referer: " url "\r\n"
"Pragma: no-cache\r\n"
"Content-type: application/x-www-form-urlencoded\r\n"
(if (and user pass)
diff -uNr tdiary.orig/tdiary.l tdiary/tdiary.l
--- tdiary.orig/tdiary.l 2003-12-02 00:32:56.000000000 +0900
+++ tdiary/tdiary.l 2005-07-21 00:18:10.445193500 +0900
@@ -131,6 +131,9 @@
(defvar *tdiary-index-rb* nil
"Name of the 'index.rb'")
+(defvar *tdiary-csrf-key* nil
+ "CSRF protection key.")
+
(defvar *tdiary-update-rb* "update.rb"
"Name of the 'update.rb'")
@@ -304,6 +307,7 @@
(pushnew (cons "year" year) post-data :test 'equal)
(pushnew (cons "month" month) post-data :test 'equal)
(pushnew (cons "day" day) post-data :test 'equal)
+ (if *tdiary-csrf-key* (pushnew (cons "csrf_protection_key" *tdiary-csrf-key*) post-data :test 'equal))
(or (equal mode "edit")
(pushnew (cons "title" (www-url-form-encode title)) post-data :test 'equal))
(pushnew (cons mode mode) post-data :test 'equal)
@@ -394,13 +398,15 @@
(switch-to-buffer buf)
(tdiary-mode)
(setf *tdiary-edit-mode* "append")
- (if replacep
+ (let (start end body title csrf-key)
(let (start end body title)
(save-excursion
(setf buf (tdiary-post "edit" *tdiary-date* nil))
(when (bufferp buf)
(save-excursion
(set-buffer buf)
+ (if (re-search-forward "<input [^>]+name=\"csrf_protection_key\" [^>]*value=\"\\([^>\"]*\\)\">" t)
+ (setf csrf-key (match-string 1)))
(re-search-forward "<input [^>]+name=\"title\" [^>]+value=\"\\([^>\"]*\\)\">" t)
(tdiary-debug (concat "R TITLE : " (match-string 1)))
(setf title (match-string 1))
@@ -411,13 +417,14 @@
(setf body (buffer-substring start end))
(set-buffer-modified-p nil)
(tdiary-debug body))
- (insert body)))
- (setf *tdiary-edit-mode* "replace")
+ (setf *tdiary-csrf-key* (and csrf-key (replace-entity-refs csrf-key)))
+ (when replacep
+ (insert body)
+ (setf *tdiary-edit-mode* "replace")))
(setf *tdiary-title* (replace-entity-refs title))
(goto-char (point-min))
(replace-entity-refs)
- (set-buffer-modified-p nil))
- (setf *tdiary-edit-mode* "append"))))
+ (set-buffer-modified-p nil))))))
(defun tdiary-new (&optional select-url)
(interactive "P")
@@ -685,6 +692,7 @@
(make-local-variable '*tdiary-diary-url*)
(make-local-variable '*tdiary-index-rb*)
(make-local-variable '*tdiary-update-rb*)
+ (make-local-variable '*tdiary-csrf-key*)
;; Enable highlight
(make-local-variable 'html-highlight-mode)
*1 パッチの量を減らすためにインデントの調整をしていないのでさらに見づらいです
と思ったら、早速新しいバージョンがでました。暫定対応ということでRefererの方にしか対応していないので、tDiary側の設定でRefererのチェックだけしてcsrf_protection_keyはチェックしないようにしました*1。
NetInstallerの使い方をすっかり忘れていたのですが、バージョンアップするときには、*NetInstaller Site*バッファでrを押してパッケージリストを更新してから、*NetInstaller Apps*バッファでバージョンアップしたいパッケージを選んでiを押します。
*1 この時点までここで設定できることにそもそも気づいていなかったのですが
以下のようなコードをPlatform SDKのAMD64用のコンパイラ*1でコンパイルすると、fooを呼び出しているところでエラーになります。テンプレートコンストラクタかテンプレートキャストオペレータのどちらかをコメントアウトすると通るようになります。VC7.1やgcc 3.4.4ではこのまま通るのですがどっちが正しいのでしょうか。
class X {};
class Y : public X {};
template<typename T>
struct Z {
explicit Z(T* p) : p_(p) {}
template<typename U> Z(Z<U>& z) : p_(z.p_) {}
template<typename U> operator Z<U>() const { return Z<U>(p_); }
T* p_;
};
void foo(Z<X> x) {
}
void bar() {
Z<Y> z(new Y());
foo(z);
}
*1 _MSC_VERは1400