Nobita/027.ISO9660のバグ


Top / Nobita / 027.ISO9660のバグ

027.ISO9660のバグ

neri さんによる御指摘

monitor.binがmonitor.cfg読んでサーバー起動してる段階でおそらくCD-ROMのルートディレクトリが1セクタ超えると
それ以降の内容が読めずにSERVERディレクトリが2セクタ目以降にあるとそのままサーバーのロードも失敗するっぽいです

検証

file_server_on linux で試したら確かにおかしかった。
ルートディレクトリにたくさんファイルがあって1セクタを越えるとおかしいとのこと。
こんな感じでたくさんファイルを作ってから動かすと確かにおかしい。

for i in `seq 1 100`; do echo "$i" > $i; done

バグ発見

確かにルートディレクトリにファイルがたくさんあると /SERVERS ディレクトリの open 時に正しく情報がとれない。
 
テストが通らなくなる。
 
monapi_cmemoryinfo* mi = monapi_file_read_directory("/SERVERS");
CPPUNIT_ASSERT_MESSAGE("readdir /SERVERS mi != NULL", mi != NULL);
monapi_directoryinfo* p = (monapi_directoryinfo*)&mi->Data[sizeof(int)];
int size = *(int*)mi->Data;
 
CPPUNIT_ASSERT_EQUAL_MESSAGE("entry count", 8, size); // ここ
 
色々調べたところ neri さんの予想通り、1セクタを越えたところの2セクタ目以降が読まれていない。
 
コードを見るとバッファには読まれているが、セクタ境界の中途半端な部分で break してしまっていた。
 
ディレクトリエントリはセクタ境界をまたがないようになっているので、セクタ境界にうまく合わせて処理を続けるようにした。
 
ついでに以前から指摘のあった大文字に統一もした。
 
Index: ISO9660/ISO9660FileSystem.cpp
===================================================================
--- ISO9660/ISO9660FileSystem.cpp       (リビジョン 4705)
+++ ISO9660/ISO9660FileSystem.cpp       (作業コピー)
@@ -397,7 +397,7 @@
         }
         else
         {
-            entry->name = string((const char*)pathEntry->name, pathEntry->length);
+            entry->name = upperCase(string((const char*)pathEntry->name, pathEntry->length));
         }
         list->push_back(entry);
 
@@ -446,7 +446,7 @@
     {   
         result = result.substr(0, result.size() - 1);
     }   
-    return result;
+    return upperCase(result);
 }
 
 void ISO9660FileSystem::setDirectoryRelation(EntryList* list, Entry* directory)
@@ -606,11 +606,14 @@
         DirectoryEntry* iEntry = (DirectoryEntry*)(buffer + position);
         string name = string(iEntry->name, iEntry->name_len);
 
-        if (iEntry->length == 0) break;
+        if (iEntry->length == 0)
+        {
+            position = ((position + SECTOR_SIZE - 1) / SECTOR_SIZE) * SECTOR_SIZE;
+            continue;
+        }
         for (EntryList::iterator i = children->begin(); i != children->end(); ++i)
         {
             Entry* child = *i;
-            if (name != child->name) continue;
+            if (upperCase(name) != child->name) continue;
 
             setDetailInformation(child, iEntry);
         }
 
テストも全て通ったので、コミットしました。
 
neri さんご指摘ありがとうございました。

コメント

コメントはありません。 コメント/Nobita/027.ISO9660のバグ?

お名前:

MENU

now: 4

リンク


最新の20件
2018-10-07 2018-09-20 2018-09-03 2018-05-09 2017-09-29 2017-01-10 2016-12-11 2016-10-04 2016-08-14 2016-05-29 2015-12-28 2013-02-25 2013-02-21 2013-02-20 2013-02-12 2013-02-11 2013-02-10
最新の20件
2010-02-01 2010-01-31 2010-01-30 2010-01-29 2010-01-16

Counter: 1806, today: 1, yesterday: 0

リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS

Last-modified: 2008-03-28 (金) 15:47:55 (3854d);  Modified by mona
PukiWiki 1.4.6 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-ji
Powered by PHP 5.2.17
HTML convert time to 0.016 sec.