2010-04-26 90 views
1

我正在編寫一個實用程序,它接收.resx文件並創建一個JavaScript對象,其中包含.resx文件中所有名稱/值對的屬性。這一切都很好,直到.resx中的一個值爲如何使用StreamWriter逐字寫入轉義字符(無需轉義)?

此經銷商接受電子訂單。

/r/n點擊訂購該經銷商的{0}。

我添加的名稱/值對的JS對象是這樣的:

streamWriter.Write(string.Format("\n{0} : \"{1}\"", kvp.Key, kvp.Value)); 

當kvp.Value =「該經銷商接受電子orders./r/nClick從這個{0}訂購經銷商「。

這會導致StreamWriter.Write()實際在「訂單」之間放置換行符。和'點擊',這自然搞砸了我的JavaScript輸出。

我已經嘗試了不同的事情@和沒有使用string.Format,但我沒有運氣。有什麼建議麼?

編輯:此應用程序在構建期間運行以獲得稍後部署的一些javascript文件,因此除了應用程序開發人員之外,任何人都無法訪問/運行此應用程序。所以,雖然我明顯需要一種逃避角色的方式,但XSS本身並不是一個真正值得關注的問題。

回答

3

當你看到這段代碼時,你的問題已經發生了。 String.Format不會將替換字符串({0}等)中的文字\n\r「擴展」爲換行符和CR,因此它必定發生在某個更早的時間點,可能在讀取.resx文件時發生。

您有兩種可能的解決方案。一,當你在評論DonaldRay的答案發現,是明確地扭轉這種替換,並用兩個字符\n替換文字換行:

kvp.Value.Replace("\r",  // <-- replaced by the C# compiler with a literal CR character 
        "\\r"); // <-- "\\" replaced by the C# compiler with a single "\", 
          // leaving the two-char string "\r" 

您需要爲可能出現在每一個字符做同樣的你的琴絃。 \ n和\ r是最常見的,然後\ t(tab);這對大多數開發工具來說可能就足夠了。

string formatted = kvp.Value.Replace("\r", "\\r") 
          .Replace("\n", "\\n") 
          .Replace("\t", "\\t"); 

或者,你可以看看上游的.resx文件讀取代碼,並設法找到並刪除了明確擴大這些字符序列的部分。如果可能的話,這將是更好的通用解決方案。

+0

我按照現在的方式做了一個粗略的傳遞。我使用XmlDocument.LoadXml()讀取.resx文件,然後使用一個ForEach(Node.SelectNodes(xpath string)),Node.ChildNodes [1] .InnerText。 看來,當我觸摸Node.ChildNodes [1] .InnerText時,特殊字符已經被擴展。 假設從XmlDocument實現切換不值得花費精力,對此有何看法? – Joel 2010-04-26 20:36:15

1

只是逃避反斜槓。

kvp.Value = kvp.Value.Replace(@"\", @"\\");

您可能需要這樣當您從RESX文件中讀取。

+0

試過這個,它不工作的原因。 .Replace似乎並不想取代\。 – Joel 2010-04-26 19:48:34

+0

好的,這是交易。我結束了這個解決方案,但語法必須是kvp.Value = kvp.Value.Replace(「\ r」,@「\\ r」)。 我認爲這是因爲「\ r」和「\ n」是字符串中的唯一字符--C#不會將單個「\」識別爲任何內容,它只是「\ n」或「\ r」字符的aprt 。 所以,更多的工作,但它似乎讓我想去的地方。我可以對此進行更多的討論/解釋或鏈接,因爲我覺得它突出了一些重要的字符串原則(我只是不知道它們是什麼!) – Joel 2010-04-26 20:06:47

+0

不,這很有意義。 '\ r'是字符串中的單個字符。當你用@「\\ r」替換這個回車符時,你將放置兩個反斜槓和一個r(因爲@符號禁止轉義字符)。當Streamwriter去寫字符串時,它會看到「\\ r」。 「\\」被解釋爲'\',並且r正常打印。 – DonaldRay 2010-04-28 20:05:22