從.Net框架Bug的提交到修復程式碼成功合併到.NET CoreFX主
問題描述
我們用SmtpClient
的SendAsync
、 SendMailAsync
非同步方法傳送郵件,並且要求使用DeliveryFormat
=
SmtpDeliveryFormat.SevenBit
格式來編碼中文內容,本來預期是郵件內容中帶中文的Subject
、Attachments file name
都會進行Base64編碼。
但實際結果是:如果郵件伺服器支援SMTPUTF8
擴充套件,那麼非同步傳送SevenBit
郵件並不會進行Base64編碼,同步方法沒有此問題。
問題根源
原因是在SmtpClient.SendMailCallback
方法中,message.BeginSend
allowUnicode
引數直接使用的ServerSupportsEai
,而不是統一的IsUnicodeSupported()
。
private void SendMailCallback(IAsyncResult result) { ...... _message.BeginSend(_writer, DeliveryMethod != SmtpDeliveryMethod.Network, ServerSupportsEai, new AsyncCallback(SendMessageCallback), result.AsyncState); ...... }
把ServerSupportsEai
改成IsUnicodeSupported()
問題解決。就這20個字元的改動~
另外附對現有帶Bug的.Net框架修復方法
比如使用的.NET Framework 4.7.2,純天然原生自帶此Bug,我們可以用我們的程式碼修復它。
最開始測試時以為此方法無效,沒想到是Hook錯了地方,換到最深層次呼叫地方,一抓一個準。
使用庫對.Net框架內方法進行Hook,找出SmtpClient.ServerSupportsEai
最結果最終是從SmtpConnection.ServerSupportsEai
得來的,也許是C#編譯後把整個呼叫過程都最佳化掉了,變成了取值的地方直接呼叫的SmtpConnection
中的方法,導致Hook前面的方法都是不會被執行,Hook SmtpConnection.ServerSupportsEai
一抓一個準。
附上Hook程式碼:
public class Hook : IMethodMonitor { public bool ServerSupportsEai { [Monitor("System.Net.Mail", "SmtpConnection")] get { Console.WriteLine("Hook"); return !true?org():false;//什麼情況下要Hook? AsyncLocal和CallContext上下文為什麼在這裡傳不進來? } } [Original] public bool org() { return false; } }
另外引出了另外一個折磨人Bug,非同步環境下,ServerSupportsEai
的呼叫棧中上下文怎麼會丟失?難道哪裡使用了類似ThreadPool.UnsafeXXX
這種效果?我們沒法透過CallContext
(AsyncLocal
)給Hook程式碼傳引數,只能寫死,不管呼叫方要不要修改返回值,都只能得到修改後的結果,尷尬不尷尬。
作者:高堅果兄弟
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3137/viewspace-2820191/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- .NET 7 預覽版2 的亮點之 NativeAOT 正式合併入 .NET 主線
- .NET LoongArch64 正式合併進入.NET
- Android熱修復原理(一)熱修復框架對比和程式碼修復Android框架
- .NET生成小程式碼,併合自定義背景圖生成推廣小程式二維碼
- .NET 中的併發程式設計程式設計
- 部落格園主題美化中BUG修復方法
- .NET 程式碼混淆工具-JIEJIE.NET
- C#/VB.NET 合併PDF頁面C#
- 開源框架 - 新 程式碼生成器 WebFirst / .NET Core框架Web
- PHP 圖片的合併,微信小程式碼合併,文字合併PHP微信小程式
- .Net Core——用程式碼寫程式碼?
- .net core使用CSRedisCore訪問Redis主從+哨兵Redis
- .Net Core微服務——Consul(4):主從、叢集微服務
- SVN使用教程:將online分支的程式碼合併到sprint分支
- 微軟修復Bug的補丁產生了新的Bug微軟
- 我的程式設計經歷,從天橋地攤Basic到西藏阿里的.Net AOT。(一,從井到Sharp)程式設計阿里
- Docker & ASP.NET Core (1):把程式碼連線到容器DockerASP.NET
- [.NET開發者的福音]一個方便易用的線上.NET程式碼編輯工具.NET Fiddle
- flexible.js 相容bug修復FlexJS
- osgi.net框架框架
- 框架庫(.NET 指南)框架
- .NET框架介紹框架
- .NET的併發程式設計(TPL程式設計)是什麼?程式設計
- Redis在.net中的使用(3)簡單的主從複製Redis
- .NET併發程式設計-資料並行程式設計並行
- .NET併發程式設計-函式閉包程式設計函式
- 從 MVC 到使用 ASP.NET Core 6.0 的最小 APIMVCASP.NETAPI
- PHP DIY 系列------框架篇:6. 簡單測試與 bug 修復PHP框架
- .NET平臺系列24:從.NET Framework遷移到.NET Core/.NET5的技術指南Framework
- 記一次Git分支合併引起的問題和修復Git
- [Net 6 AspNetCore Bug] 解決返回IAsyncEnumerable<T>型別時丟擲的OperationCanceledException會被AspNetCore 框架吞掉的BugNetCore型別Exception框架
- redis cluster 故障後,主從位於不同節點的修復。Redis
- 使用.NET Interactive Notebook探索程式碼
- Jenkins file一行程式碼部署.NET程式到K8SJenkins行程K8S
- 併發程式設計-9.在 .NET 中使用併發集合程式設計
- .Net Core 使用 CSRedisCore 訪問 Redis 的哨兵和主從複製Redis
- CSS之樣式無效BUG的修復CSS
- 被冰封的 Bug:Fishhook Crash 修復紀實Hook