[첫화면으로]UseModWiki소스수정/버그또는문제점해결

마지막으로 [b]

5 번째 수정본
1. 버그 또는 문제점 해결
1.1. fullsearch 와 titlesearch 매크로의 출력 형식 변경
1.2. pre 태그 안에서 부등호 표기 문제 해결
1.3. 사이트 로고 표시 문제 해결
1.4. 동일한 영어단어로 끝나는 헤드라인들이 있을 경우 <toc> 가 제대로 동작하지 않는 문제 해결
1.5. 한글이 포함된 인터위키 문제 해결
1.6. history 매크로 문제 해결
1.7. user 디렉토리를 생성하지 못하는 문제 해결
1.8. 잠겨 있는 페이지를 삭제 또는 이름을 변경할 때 lock 도 같이 처리
1.9. 사용자 아이디의 첫글자를 무조건 대문자로 만듦
1.10. 다른 사용자의 암호를 변경할 수 있는 문제 해결
1.11. 페이지를 삭제 또는 이름을 변경할 때 cache 화일도 같이 처리
1.12. REDIRECT 되는 페이지의 캐쉬 화일 문제 해결
1.13. 미리보기 화면에서 <toc> 가 제대로 동작하지 않는 문제 해결
1.14. ==== 충돌문제 해결
1.15. 상대경로로 적은 URL 처리
1.16. 사용자 암호를 암호화하여 저장
1.17. 환경설정에서 사용할 수 없는 아이디를 넣었을 때의 처리 문제 해결
1.18. 로그아웃 직후에 상단메뉴에 여전히 로그아웃 링크가 남아있는 문제 해결
1.19. 로그인 실패시 상단 메뉴의 잘못된 출력 해결
1.20. 이모티콘 패턴 수정
1.21. Full Link List 버그 수정
1.22. GetFullLinkList() 함수의 버그 수정
1.23. goto 매크로 문제 해결
1.24. 테이블이 아닌 || 처리 문제 해결

1. 버그 또는 문제점 해결

1.1. fullsearch 와 titlesearch 매크로의 출력 형식 변경

sub MacroTitleSearch {
    ...
      $txt .= &GetPageLink($name) . "<br>";   # 원래는 " " 인데, "<br>" 로 수정했음.
    ...
        $txt .= &GetPageLink($name) . "<br>";
}
sub MacroFullSearch()
{
    ...
    $txt .= &GetPageLink($pagename) . "<br>";
    ...
}

1.2. pre 태그 안에서 부등호 표기 문제 해결

sub GetTextArea {
        my ($name, $text, $rows, $cols) = @_;
        $text =~ s/(\&)/\&amp;/g;          # 이 줄을 추가해 준다.
        ...
}

1.3. 사이트 로고 표시 문제 해결

sub GetHeader {
        ...
        if ($id ne '') {
#               $result .= $q->h1(&GetSearchLink($id));            이 부분을
                $result .= $q->h1($header . &GetSearchLink($id));  # 이렇게 고쳐줄 것
        } else {
                $result .= $q->h1($header . $title);
        }
        ...
}

1.4. 동일한 영어단어로 끝나는 헤드라인들이 있을 경우 <toc> 가 제대로 동작하지 않는 문제 해결

sub WikiHeadingNumber {
        ...
        # Cook anchor by canonicalizing $text.
# 아래 여섯 줄은 불필요. 주석처리
#       $anchor = $text;
#       $anchor =~ s/\<.*?\>//g;
#       $anchor =~ s/\W/_/g;
#       $anchor =~ s/__+/_/g;
#       $anchor =~ s/^_//;
#       $anchor =~ s/_$//;

#       $anchor = '_' . (join '_', @HeadingNumbers) unless $anchor; # Last ditch effort    이 줄을
        $anchor = 'H_' . (join '_', @HeadingNumbers);                                      # unless 뒤를 잘라서 이렇게 고친다
        ...
}

1.5. 한글이 포함된 인터위키 문제 해결

sub SplitUrlPunct {
    ....
    $punct = "";

#   아래 두 줄의 xc0 을 x80 으로 바꿈
#   ($punct) = ($url =~ /([^a-zA-Z0-9\/\xc0-\xff]+)$/);
#   $url =~ s/([^a-zA-Z0-9\/\xc0-\xff]+)$//;

    ($punct) = ($url =~ /([^a-zA-Z0-9\/\x80-\xff]+)$/);
    $url =~ s/([^a-zA-Z0-9\/\x80-\xff]+)$//;

    return ($url, $punct);
}

1.6. history 매크로 문제 해결

sub MacroHistory {
    ...
    $html .= "<table border='0' cellpadding=0 cellspacing=0 width='90%'><tr>";

#   $html .= &GetHistoryLine($DocID, $Page{'text_default'}, 0, 1);   이 줄을 다음 줄로 변경
    $html .= &GetHistoryLine($DocID, $Page{'text_default'}, 0, 0);

    &OpenKeptRevisions('text_default');
    ...
        next  if ($_ eq "");  # (needed?)

#       $html .= &GetHistoryLine($DocID, $KeptRevisions{$_}, 0, 0);   이 줄을 다음 줄로 변경
        $html .= &GetHistoryLine($DocID, $KeptRevisions{$_}, 0, $i);

    }
    $html .= "<tr><td align='center'><input type='submit' value='변경 비교'/>  </td><td>&nbsp;</td></table></form>\n";
    return $html;
}

1.7. user 디렉토리를 생성하지 못하는 문제 해결

sub SaveUserData {
    my ($userFile, $data);
    # 다음 줄 추가
    &CreateDir($UserDir);

    $userFile = &UserDataFilename($UserID);
    $data = join($FS1, %UserData);
    &WriteStringToFile($userFile, $data);
}

1.8. 잠겨 있는 페이지를 삭제 또는 이름을 변경할 때 lock 도 같이 처리

sub DeletePage {
    ...
    $fname = $KeepDir . "/" . &GetPageDirectory($page) .  "/$page.kp";
    unlink($fname)  if (-f $fname);
### 아래 두 줄 추가
    $fname = &GetLockedPageFile($page);
    unlink($fname) if (-f $fname);
### 여기까지
    unlink($IndexFile)  if ($UseIndex);
    ...
}
sub RenamePage {
    ...
    rename($oldkeep,  $newkeep);
    unlink($IndexFile)  if ($UseIndex);
### 다음 코드를 삽입
    my ($oldlock, $newlock);
    $oldlock = &GetLockedPageFile($old);
    if (-f $oldlock) {
        $newlock = &GetLockedPageFile($new);
        rename($oldlock, $newlock) || die "error while renaming lock";
    }
### 여기까지

    &EditRecentChanges(2, $old, $new)  if ($doRC);
    if ($doText) {
    ...
}

1.9. 사용자 아이디의 첫글자를 무조건 대문자로 만듦

sub DoUpdatePrefs {
    ...
    print '<br>';
### 다음 두 줄을 수정한다.
#   $UserID = &GetParam("p_username",  "");
#   $username = &GetParam("p_username",  "");
    $UserID = &FreeToNormal(&GetParam("p_username",  ""));
    $username = &FreeToNormal(&GetParam("p_username",  ""));
###
    if ($FreeLinks) {
    ...
}

sub DoLogin {
    my ($uid, $password, $success);

    $success = 0;
### 다음 한 줄을 수정한다
#   $uid = &GetParam("p_userid", "");
    $uid = &FreeToNormal(&GetParam("p_userid", ""));
###
    $password = &GetParam("p_password",  "");
    ...
}

1.10. 다른 사용자의 암호를 변경할 수 있는 문제 해결

sub DoUpdatePrefs {
    ...
#   아래의 두 줄은 "사용자 아이디의 첫글자를 무조건 대문자로 만듦"에서 패치된 부분이다
#   원래코드에는 FreeToNormal(  ) 로 둘러싸여 있지 않다.
    $UserID = &FreeToNormal(&GetParam("p_username",  ""));
    $username = &FreeToNormal(&GetParam("p_username",  ""));
### 다음 부분을 추가한다
    my ($status, $data) = &ReadFile(&UserDataFilename($UserID));
    if ($status) {
        if ((!(&UserIsAdmin)) && ($UserData{'id'} ne $UserID)) {
            print T('Error: Can not update prefs. That ID already exists and does not match your ID.'). '<br>';
            print &GetCommonFooter();
            return;
        }
    }
### 여기까지
    if ($FreeLinks) {
        $username =~ s/^\[\[(.+)\]\]/$1/;  # Remove [[ and ]] if added
    ...
}

1.11. 페이지를 삭제 또는 이름을 변경할 때 cache 화일도 같이 처리

sub DeletePage {
    ...
    $fname = $KeepDir . "/" . &GetPageDirectory($page) .  "/$page.kp";
    unlink($fname)  if (-f $fname);
### 예전에 lock 화일 관련 패치한 부분
    $fname = &GetLockedPageFile($page);
    unlink($fname) if (-f $fname);
### 다음 라인을 추가로 삽입
    &UnlinkHtmlCache($page);
###
    unlink($IndexFile)  if ($UseIndex);
    &EditRecentChanges(1, $page, "")  if ($doRC);  # Delete page
    # Currently don't do anything with page text
}
}}} 
: RenamePage 에서는, lck 화일과 달리 cache 화일은 그냥 삭제한다.
{{{perl
sub RenamePage {
    ...
### 이전 패치에서 추가한 lck 화일 관련 부분
    my ($oldlock, $newlock);
    $oldlock = &GetLockedPageFile($old);
    if (-f $oldlock) {
        $newlock = &GetLockedPageFile($new);
        rename($oldlock, $newlock) || die "error while renaming lock";
    }
### 아래 라인을 추가로 삽입
    &UnlinkHtmlCache($old);
###
    &EditRecentChanges(2, $old, $new)  if ($doRC);
    if ($doText) {
        &BuildLinkIndexPage($new);  # Keep index up-to-date
        &RenameTextLinks($old, $new);
    }
}

1.12. REDIRECT 되는 페이지의 캐쉬 화일 문제 해결

서론이 매우 길었는데, 정작 수정할 부분은 너무도 간단하다.
sub DoBrowseRequest {
    ...
    return  if ($showDiff || ($revision ne ''));  # Don't cache special version
### 다음 라인의 if 구문에 조건 하나만 더 추가해주면 된다.
#   &UpdateHtmlCache($id, $fullHtml)  if $UseCache;
    &UpdateHtmlCache($id, $fullHtml)  if ($UseCache && ($oldId eq ''));
###
}

1.13. 미리보기 화면에서 <toc> 가 제대로 동작하지 않는 문제 해결

sub WikiHeadingNumber {
    ...
### 다음 라인을 수정
#   $TableOfContents .= $number . &ScriptLink("$OpenPageName#$anchor",$text) . "</dd>\n<dt> </dt><dd>";
    $TableOfContents .= $number . "<a href=\"#$anchor\">" . $text . "</a></dd>\n<dt> </dt><dd>";
###
    return &StoreHref(" name=\"$anchor\"") . $number;
}

1.14. ==== 충돌문제 해결

sub CommonMarkup {
    ...
        $_ = &MacroSubst($_);               # luke added
### 다음을 교체
#       if ($ThinLine) {
#           s/----+/<hr noshade size=1>/g;
#           s/====+/<hr noshade size=2>/g;
#       } else {
#           s/----+/<hr>/g;
#       }

        if ($ThinLine) {
            s/--------+/<hr noshade style="height:5px">/g;
            s/-------+/<hr noshade style="height:4px">/g;
            s/------+/<hr noshade style="height:3px">/g;
            s/-----+/<hr noshade style="height:2px">/g;
            s/----+/<hr noshade style="height:1px">/g;
        } else {
            s/----+/<hr>/g;
        }
### 여기까지
    }
    if ($doLines) { # 0 = no line-oriented, 1 or 2 = do line-oriented
    ...

1.15. 상대경로로 적은 URL 처리

다른 패치 (새창으로 열기 아이콘, 그림 주소 보이기) 를 이미 적용했을 경우 소스코드가 아래와는 다르게 나올 것이다. 알아서 잘 처리하라. ;-)
sub UrlLink {
    ...
        return ("<img $ImageTag src=\"$name\">", $punct);
    }

### 여기를 추가해 준다.
    my $protocol;
    ($protocol, $name) = ($1, $2) if ($name =~ /^(https?:)(.*)/ && $2 !~ /^\/\//);
###

### return 문에 $protocol 을 추가
#   return ("<a href=\"$name\">$name</a>", $punct);
    return ("<a href=\"$name\">$protocol$name</a>", $punct);
}

1.16. 사용자 암호를 암호화하여 저장

...
package UseModWiki;
use strict;
### 다음 두 줄 추가
use vars qw($HashKey);
$HashKey = "salt"; # 2-character string
###
sub UserIsAdmin {
    ...
    foreach (split(/\s+/, $AdminPass)) {
        next  if ($_ eq "");
### 다음 라인 교체
#       return 1  if ($userPassword eq $_);
        return 1  if (crypt($_, $userPassword) eq $userPassword);
###
    }
    return 0;
}
sub UserIsEditor {
    ...
    foreach (split(/\s+/, $EditPass)) {
        next  if ($_ eq "");
### 다음 라인 교체
#       return 1  if ($userPassword eq $_);
        return 1  if (crypt($_, $userPassword) eq $userPassword);
###
    }
    return 0;
}
sub DoUpdatePrefs {
    my ($username, $password);
### 다음 라인 추가
    my $hashpass = "";
###
    ...
    $password = &GetParam("p_password",  "");
### 다음 라인 추가
    $hashpass = crypt($password, $HashKey);
###
    if ($password eq "") {
        print T('Password removed.'), '<br>';
        undef $UserData{'password'};
    } elsif ($password ne "*") {
        print T('Password changed.'), '<br>';
### 다음 라인 교체
#       $UserData{'password'} = $password;
        $UserData{'password'} = $hashpass;
###
    }
    if ($AdminPass ne "") {
        $password = &GetParam("p_adminpw",  "");
### 다음 라인 추가
        $hashpass = crypt($password, $HashKey);
###
        if ($password eq "") {
            print T('Administrator password removed.'), '<br>';
            undef $UserData{'adminpw'};
        } elsif ($password ne "*") {
            print T('Administrator password changed.'), '<br>';
### 다음 라인 교체
#           $UserData{'adminpw'} = $password;
            $UserData{'adminpw'} = $hashpass;
###
            if (&UserIsAdmin()) {
                print T('User has administrative abilities.'), '<br>';
    ...
}
sub DoLogin {
    ...
        &LoadUserData();
### 다음 라인 교체
#       if (defined($UserData{'password'}) &&
#               ($UserData{'password'} eq $password)) {
        if (defined($UserData{'password'}) &&
                (crypt($password, $UserData{'password'}) eq $UserData{'password'})) {
###
            $SetCookie{'id'} = $uid;
    ...

1.17. 환경설정에서 사용할 수 없는 아이디를 넣었을 때의 처리 문제 해결

sub DoUpdatePrefs {
    ...
    if ($FreeLinks) {
        $username =~ s/^\[\[(.+)\]\]/$1/;  # Remove [[ and ]] if added
        $username =  &FreeToNormal($username);
        $username =~ s/_/ /g;
    }
### 아래 if 문의 처음 네 블럭을 수정한다.
#   if ($username eq "") {
#       print T('UserName removed.'), '<br>';
#       undef $UserData{'username'};
#   } elsif ((!$FreeLinks) && (!($username =~ /^$LinkPattern$/))) {
#       print Ts('Invalid UserName %s: not saved.', $username), "<br>\n";
#   } elsif ($FreeLinks && (!($username =~ /^$FreeLinkPattern$/))) {
#       print Ts('Invalid UserName %s: not saved.', $username), "<br>\n";
#   } elsif (length($username) > 50) {  # Too long
#       print T('UserName must be 50 characters or less. (not saved)'), "<br>\n";
    if (length($username) < 4) {
        print T('UserName must be 4 characters or more. (not saved)'), "<br>\n";
        $UserID = 0;
        print &ScriptLink("action=editprefs", T('Try Again'));
        print &GetCommonFooter();
        return;
    } elsif ((!$FreeLinks) && (!($username =~ /^$LinkPattern$/))) {
        print Ts('Invalid UserName %s: not saved.', $username), "<br>\n";
        $UserID = 0;
        print &ScriptLink("action=editprefs", T('Try Again'));
        print &GetCommonFooter();
        return;
    } elsif ($FreeLinks && (!($username =~ /^$FreeLinkPattern$/))) {
        print Ts('Invalid UserName %s: not saved.', $username), "<br>\n";
        $UserID = 0;
        print &ScriptLink("action=editprefs", T('Try Again'));
        print &GetCommonFooter();
        return;
    } elsif (length($username) > 50) {  # Too long
        print T('UserName must be 50 characters or less. (not saved)'), "<br>\n";
        $UserID = 0;
        print &ScriptLink("action=editprefs", T('Try Again'));
        print &GetCommonFooter();
        return;
### 여기까지
    } else {
        print Ts('UserName %s saved.', $username), '<br>';
        $UserData{'username'} = $username;
    }
    ...
}

1.18. 로그아웃 직후에 상단메뉴에 여전히 로그아웃 링크가 남아있는 문제 해결

sub DoLogout {
    ...
    $SetCookie{'rev'} = 1;

### print 문의 앞뒤로 추가한다.
    my $tempUserID = $UserID;                       # 추가
    $UserID = "113";                                # 추가
    print &GetHeader('', T('Logout Results'), '');
    $UserID = $tempUserID;                          # 추가
###
    if (($UserID ne "113") && ($UserID ne "112")) {
        print Ts('Logout for user ID %s complete.', $UserID);
    }
    ...
}

1.19. 로그인 실패시 상단 메뉴의 잘못된 출력 해결

sub DoLogin {
    ...
        else {
            $SetCookie{'id'} = "";
### 다음 두 라인 추가
            $UserID = "";
            &LoadUserData();
###
        }
    }
### 다음 print 문과 if 문을 통채로 바꾼다.
#   print &GetHeader('', T('Login Results'), '');
#
#   if ($success) {
#       print Ts('Login for user ID %s complete.', $uid);
#       %UserCookie = %SetCookie;
#   } else {
#       print Ts('Login for user ID %s failed.', $uid);
#       %UserCookie = %SetCookie;
#       $UserID = "";
#   }
    if ($success) {
        print &GetHeader('', T('Login completed'), '');
        print Ts('Login for user ID %s complete.', $uid);
        %UserCookie = %SetCookie;
    } else {
        print &GetHeader('', T('Login failed'), '');
        print Ts('Login for user ID %s failed.', $uid);
        %UserCookie = %SetCookie;
        $UserID = "";
        print "<br>" . &ScriptLink("action=login", T('Try Again'));
    }
###
    ...
}

1.20. 이모티콘 패턴 수정

sub EmoticonSubst {
    ...
    # 몇몇 곳에 [^A-z] 를 추가한다.
        $txt =~ s/\s\^[oO_\-]*\^[;]*/$e2/g;
        $txt =~ s/\s-[_]+-[;]*/$e7/g;
        $txt =~ s/\so\.O[^A-z]/$e5/g;
        $txt =~ s/\s\*\.\*/$e5/g;
        $txt =~ s/\s\=\.\=[;]*/$e7/g;
        $txt =~ s/\s\:-[sS][^A-z]/$e7/g;

        $txt =~ s/\s\:[-]*D[^A-z]/$e2/g;
        $txt =~ s/\s\:[-]*\([^A-z]/$e3/g;
        $txt =~ s/\s\:[-]*\)[^A-z]/$e4/g;
        $txt =~ s/\s\:[-]*[oO][^A-z]/$e5/g;
        $txt =~ s/\s\:[-]*[pP][^A-z]/$e6/g;
        $txt =~ s/\s\;[-]*\)[^A-z]/$e8/g;
    }

    return $txt;
}

1.21. Full Link List 버그 수정

sub PrintLinkList {
    ...
    foreach $pagelines (@_) {
        @links = ();
### 다음 라인을 교체
#       foreach $page (split(' ', $pagelines)) {
        my @pages = split(' ', $pagelines);
        foreach $page (@pages) {
###
            if ($page =~ /\:/) {  # URL or InterWiki form
    ...
            } else {
                if ($pgExists{$page}) {
                    $link = &GetPageLink($page);
### 다음 라인 추가
                } elsif ($page =~ /^\// && $pgExists{(split ('/',$pages[0]))[0].$page}) {
                    ($link, $extra) = &GetPageLinkText((split ('/',$pages[0]))[0].$page, $page);
###
                } else {
                    $link = $page;
    ...
}

1.22. GetFullLinkList() 함수의 버그 수정

sub GetFullLinkList {
    ...
        foreach $link (@links) {
            $seen{$link}++;
            if (($unique > 0) && ($seen{$link} != 1)) {
                next;
            }
### 다음 단락을 수정
#           if (($exists == 0) && ($pgExists{$link} == 1)) {
#               next;
#           }
#           if (($exists == 1) && ($pgExists{$link} != 1)) {
#               next;
#           }

            my $link2 = $link;
            $link2 = (split ('/',$name))[0]."$link" if ($link =~ /^\//);
            if (($exists == 0) && ($pgExists{$link2} == 1)) {
                next;
            }
            if (($exists == 1) && ($pgExists{$link2} != 1)) {
                next;
            }
### 여기까지
            if (($search ne "") && !($link =~ /$search/)) {
                next;
            }
    ...
}

1.23. goto 매크로 문제 해결

sub DoBrowseRequest {
    ...
    if ($action eq 'browse') {
        if ($FreeLinks && (!-f &GetPageFile($id))) {
            $id = &FreeToNormal($id);
        }
        if (($NotFoundPg ne '') && (!-f &GetPageFile($id))) {
            $id = $NotFoundPg;
        }
### 추가
        if ($id eq '') {
            $id = $HomePage;
        }
###
        &BrowsePage($id)  if &ValidIdOrDie($id);
        return 1;
    ...
}
sub MacroGoto {
    my ($string) = @_;

    return
### 아래 단락을 수정
#       "<form name=goto><input name=wkl type=text size=10 value=$string>" .
#       "<input type=button value=\"" . T('Go') . "\" onclick='javascript:document.location.href=\"$ScriptName?\"+document.goto.wkl.value'>" .
#       "</form>";
        "<form name=goto><input type=\"hidden\" name=\"action\" value=\"browse\" id=\"hidden-box\">".
        "<input name='id' type\text size=10 value=$string>" . "&nbsp;" .
        "<input type=submit value=\"". T('Go') . "\">".
        "</form>";
###
###############
}

1.24. 테이블이 아닌 || 처리 문제 해결

sub WikiLinesToHtml {
    ...
        while (@htmlStack > $depth) {   # Close tags as needed
        #  $pageHtml .=  "</" . pop(@htmlStack) . ">\n";        -- deleted luke
            $tag = pop(@htmlStack);                             # added luke
            if ($tag eq "TABLE") {
### 다음 두 라인 교체
#               $pageHtml .=  "</TR>\n";
#               $tag = "table"
                $TableMode = 0;
###
            };
            $pageHtml .=  "</" . $tag . ">\n";                  # added end luke
        }
    ...
}

이 수정본 편집일: 2002-12-18 2:21 pm (변경사항 [d])
Permalink | 변경내역 보기 [h] | 현재 수정본 보기 | 5 번째 수정본 소스 보기