回文章列表
作者luzi.bbs@MSIA.pine.ncu.edu.tw (膛筐р陑), 信區: firebird
標題FireBird2.X刉壺文摘功能BUG
時間大馬同學會 大紅花的國度 (Thu Apr 1 02:17:41 1999)
轉信站: GIBBS!egg.mm.ntut!MSIA
Origin: msia.pine.ncu.edu.tw

(先嘆一口气,今天到3:00am以為可以睡覺了的,突然發現這么
一個BUG,一直弄到4:30才總算搞定,赶緊寫下一篇文章准備向所有有
這個BUG的BBS站站長要XO)

一. 首先測試一下你的BBS站有沒有這個問題
   (只有版主權限的可以在本版測試)
    1. 最好找一個沒設過文摘的版面來測試,比如test,notpad版
       然后按文章順序依次將3篇文章收入文摘,(三篇足夠測試了)
       即先g第X篇,再g第X+1篇,再g第X+2篇。
    2. 好,現在看看文摘模式,應該依次有第X,X+1,X+2篇文章的標題
    3. 回到普通模式,取消第X+1篇文章的文摘標記(再按一下g)
    4. 現在再看看文摘模式里的文章,顯示的是第X,X+1的標題
       這証明你的BBS系統存在這個BUG

二. 哪里來的BUG
    (開始我一直以為是我移植老站代碼到新站造成的,對比了半天相關的新舊代碼,
     發現沒有什么不同,于是只好怀疑FB系統的原始代碼了,只是不敢相信這個一個
     常用的功能居然存在BUG)

    1. 先看看bbs.c里的刪除文摘的函數int dele_digest(dname,direc)
      它調用下面這個語句去搜索digest_name(文摘的文件名)在目錄文件new_dir里
      的位置,返回相關的fileheader結构給fh,其中cmpfilename是用來比較讀取
      到的fileheader->filename与digest_name是否匹配的函數。
search_record(new_dir, &fh, sizeof(fh), cmpfilename, digest_name);

    2. 再看看search_record()函數,它每讀取一個fileheader結构就調用
        if((*fptr)(farg,rptr)) 去比較异同,在dele_digest的調用中
       即等同于調用 comfilename(digest_name,&fh);

    3. 再看看comfilename函數
           int cmpfilename(struct fileheader *fhdr)
              {
                if(!strncmp(fhdr->filename,currfile,STRLEN)) return 1 ;
                return 0 ;
               }
       天!居然和第2步調用的接口不一樣。
       首先digest_name的定義是 char[STRLEN],而不是srtuct fileheader;
       不過好在struct fileheader里的第一個item就是char filename[STRLEN];
       在這個函數里歪打正著沒有內存指針錯誤。
       但是它比較的卻是digest_name和currentfile,faint..

    4. 隙�正曾惡urrentfile岆妦繫陲陲ㄛ涴�棵й遘鶲姥祫縑�
       珨眻梑善郔輪珨棒跤currentfile董硉腔華源ㄛ婓dele_digest滲杅爵ㄛ
       撈覃蚚search_record()ヶㄛ�棵й遝隞牴�腔strcpy(currfile,digest_name);
       埻懂涴跺comfilename腔賦彆箝隅峈淩ㄛ稱稱ㄛ垀眕search_record殿隙腔硉
       嗣圉岆菴珨沭暮翹腔硉﹝

    5. 涴繫珨懂ㄛ渣昫憩岆....(嬪賸ㄛ擱腕迡賸 :( )

��. 賤樵BUG
   郔疑腔源楊絞�銘о埮碟棍遘鐼omfilename腔滲杅懂巠茼search_record()腔覃蚚徽
   饒繫饒珨曆strcpy(currentfile,digest_name)岆祥岆憩羶蚚賸儸ˋ
   no,no,no,遜岆衄蚚腔ㄛ狟醱delete_file滲杅猁蚚善坳﹝
   鍚俋艘賸comfilename腔埭鎢珩憩眭耋徽ㄛ坳掀誕腔岆strncmp(str1,str2,STRLEN)
   奧祥奀strcmp()ㄛ垀眕斕郔疑蚚strncpy(currentfile,str,STRLEN);
   參bbs.c爵饒虳垀衄蚚strcpy(currentfile,str)腔逄曆飲蜊傖strncpy勘﹝
   祥徹疑砓憩岆dele_digest滲杅爵腔猁蜊ㄛ梗腔滲杅飲蚚勤賸ㄛ裞裞

   扂忒芛腔FireBird 2.5X, 2.66M唳腔埭鎢飲衄涴跺BUGㄛ砑斛岆珨跺橾BUG(崋繫芼��
   砑れ賸奠隱眅)

修正FireBird 2.X 刪除文摘功能的BUG 
 
一、在bbs.c里添加下面這段函數代碼 
int 
cmpdigestfilename(digest_name,fhdr) 
char *digest_name; 
struct fileheader *fhdr ; 
{ 
    if(!strcmp(fhdr->filename,digest_name)) 
        return 1 ; 
    return 0 ; 
}     /* comapare file names for dele_digest function. Luzi 99.3.30 */ 
 
二、然后用下面的代碼替換掉原來bbs.c里的dele_digest函數 
int 
dele_digest(dname,direc)          /* updated bye Luzi 99.3.30 */ 
char *dname; 
char *direc; 
{ 
     char digest_name[STRLEN]; 
     char new_dir[STRLEN]; 
     char buf[STRLEN]; 
     char *ptr; 
     struct fileheader fh; 
     int  pos; 
 
     strncpy(digest_name,dname,STRLEN);      
     strcpy(new_dir,direc); 
 
     digest_name[0]='G'; 
     ptr = strrchr(new_dir, '/') + 1; 
     strcpy(ptr, DIGEST_DIR); 
     strncpy(buf,currfile,STRLEN); 
     strncpy(currfile,digest_name,STRLEN); 
     pos=search_record(new_dir, &fh, sizeof(fh), cmpdigestfilename, digest_name); 
     if(pos<=0) 
     { 
        return; 
     } 
     delete_file(new_dir,sizeof(struct fileheader),pos,cmpfilename); 
     strncpy(currfile,buf,STRLEN); 
     *ptr='\0'; 
     sprintf(buf,"%s%s",new_dir,digest_name); 
     unlink(buf); 
     return; 
} 
 

--
※ 來源:‧大紅花的國度 MSIA.pine.ncu.edu.tw‧[FROM: 202.96.134.135]
文章選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻