تحية لجميع عشاق علة. سيأتي العام الجديد قريبًا ، لذلك حان الوقت لتقييم السنة التي تغادر. حسب التقاليد ، تم تصنيف الأخطاء الأكثر إثارة للاهتمام التي اكتشفها فريق PVS-Studio في مشاريع C # المفتوحة لعام 2019. هل انت جاهز ثم لنبدأ.
المركز العاشر: "إرباك الجميع"
V3066 ترتيب غير صحيح محتمل للوسيطات تم تمريره إلى طريقة "AdjustCellBorderStyle": 'isFirstDisplayedRow' و 'isFirstDisplayedColumn'. DataGridViewComboBoxCell.cs 1934
protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) { .... dgvabsEffective = AdjustCellBorderStyle( DataGridView.AdvancedCellBorderStyle, dgvabsPlaceholder, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedRow,
خطأ من مقالة "
WinForms: أخطاء ، Holmes ". يشير المحلل إلى أنه عند تمرير الوسائط إلى الطريقة ، تم عكس الوسيطتين الأخيرتين. ألقِ نظرة على
إعلان AdjustCellBorderStyle :
public virtual DataGridViewAdvancedBorderStyle AdjustCellBorderStyle( DataGridViewAdvancedBorderStyledataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) { .... }
يبدو أن المحلل هو الصحيح. في كثير من الأحيان ، يتم تمرير بعض الحجج عمدا بترتيب عكسي ، على سبيل المثال ، من أجل مبادلة بعض المتغيرات. لكن لا يبدو أن هذا هو الحال بالضبط. أولاً ، يتم خلط متغيرات نوع
منطقي . ثانياً ، أسماء الطرق شائعة أيضًا: لا يوجد "تبديل" أو "عكس". بالإضافة إلى ذلك ، ليس من الصعب جدًا ارتكاب خطأ مثل هذا: غالبًا ما يتصور الناس ترتيب زوج الصف / العمود بشكل مختلف.
المركز التاسع: "اللانهائي قريب"
V3110 العودية المحتملة لانهائية داخل طريقة 'TryValidateModel'. PrefixedModuleUpdater.cs 48
public bool TryValidateModel(object model, string prefix) { return TryValidateModel(model, Prefix(prefix)); }
خطأ من المقال "
البحث عن الأخطاء وتحليلها في كود CMS من Orchard ". لقد تم ارتكاب خطأ يؤدي إلى تكرار غير محدود. لفهم كيفية حدوث هذا الخطأ ، تحتاج إلى إلقاء نظرة على التحميل الزائد لطريقة
TryValidateModel :
public bool TryValidateModel(object model) { return _updateModel.TryValidateModel(model); }
من المحتمل أنه في الحالة الأولى ، يجب استخدام استدعاء النموذج:
public bool TryValidateModel(object model, string prefix) { return _updateModel.TryValidateModel(model, Prefix(prefix)); }
التعليمات البرمجية المترجمة لأن
_updateModel من النوع
IUpdateModel ، ويقوم الفصل الحالي أيضًا بتنفيذ واجهة
IUpdateModel .
المركز الثامن: "جرب ، ابحث"
V3091 التحليل التجريبي. من الممكن وجود خطأ مطبعي داخل السلسلة الحرفية: "معرف مجموعة الإدارة". كلمة "معرف" مشبوهة. الثوابت. 36
public class HelpMessages { public const string SubscriptionId = "Subscription Id of the subscription associated with the management"; public const string GroupId = "Management Group Id";
كان الخطأ من مقال "
Azure PowerShell:" غير ضار بشكل أساسي " . يشتبه المحلل في أن ثابت
GroupName تمت تهيئته بسلسلة خطأ. من المحتمل أن يكون هناك شيء مثل
" اسم مجموعة الإدارة " . من الصعب الحكم على مدى خطورة هذا الخطأ ، لكنه نادر الحدوث بشكل فريد من الصعب اكتشافه.
المركز السابع: "تم تجاهله للتو"
V3078 سيتم فقد ترتيب الفرز الأصلي بعد استدعاء متكرر لأسلوب "OrderBy". استخدم طريقة "ThenBy" للحفاظ على التصنيف الأصلي. GridModel.Selection.cs 107
internal partial class GridModel { private void BuildCellSelectionRegions(....) { .... this.MergeCellSelectionRegions(selectedItemsInView .OrderBy(c => c.Column.ItemInfo.LayoutInfo.Line) .OrderBy(c => c.RowItemInfo.LayoutInfo.Line)); } }
خطأ من المقال "
فحص Telerik UI لـ UWP للتعرف على PVS-Studio ". بسبب إعادة استخدام
OrderBy لمجموعة مصنفة بالفعل ، سيتم فقد نتيجة الفرز السابق. يجب عليك استخدام
ThenBy :
this.MergeCellSelectionRegions(selectedItemsInView .OrderBy(c => c.Column.ItemInfo.LayoutInfo.Line) .ThenBy(c => c.RowItemInfo.LayoutInfo.Line));
يتم ارتكاب مثل هذه الأخطاء من خلال الإهمال أو الجهل. أعتقد أن نسخ اللصق هو المسؤول.
المركز السادس: "تم توثيق الكود"
V3009 من الغريب أن هذه الطريقة تُرجع دائمًا نفس القيمة "صواب". MaskedTextProvider.cs 1529
public bool Remove(out int testPosition, out MaskedTextResultHint resultHint) { .... if (lastAssignedPos == INVALID_INDEX) { .... return true;
خطأ من المقال "
التحقق من الكود المصدري لمكتبات .NET Core باستخدام محلل ثابت PVS-Studio ". الطريقة سوف تعود دائما
صحيح . نعم ، هذا خطأ ، لكن هناك شيء آخر يثير الفضول. تعليق مفصل مرفق بالطريقة:
يزيل الحرف الأخير من السلسلة المنسقة. (إزالة الحرف الأخير في السلسلة الافتراضية). عند الخروج ، يحتوي param out على الموضع الذي تم فيه تنفيذ العملية بالفعل. هذا الموقف بالنسبة لسلسلة الاختبار. يوفر MaskedTextResultHint out param مزيدًا من المعلومات حول نتيجة العملية. إرجاع صحيح عند النجاح ، خطأ .ركز على الجملة الأخيرة. لكن من يقرأ هذه التعليقات؟ لكن على محمل الجد ، فإن مثل هذا الخطأ يزحف بسهولة ، على سبيل المثال ، عند إعادة بيع أو تصحيح الأخطاء. لقد أردنا التحقق من الخيار عندما تكون نتيجة الطريقة
صحيحة دائمًا ، حسنًا ، لقد نسينا أن نعيد كل شيء كما كان في السابق.
المركز الخامس: "فهرسة لي ، على الفور!"
V3102 وصول مشبوه إلى عنصر كائن "seq" بواسطة فهرس ثابت داخل حلقة. XmlQueryRuntime.cs 738
public bool MatchesXmlType(IList<XPathItem> seq, ....) { .... for (int i = 0; i < seq.Count; i++) { if (!CreateXmlType(seq[0]).IsSubtypeOf(....)) return false; } return true; }
خطأ من المقال "
التحقق من الكود المصدري لمكتبات .NET Core باستخدام محلل ثابت PVS-Studio ". عند عبور مجموعة
seq ، تستخدم حلقة
for عن طريق الخطأ الوصول فقط إلى العنصر الأول في جميع التكرارات (الفهرس 0 بدلاً من
i ).
المركز الرابع: "مجرد دولار ولا يكفي"
V3138 حرفية السلسلة تحتوي على تعبير محتمل محتمل. النظر في التفتيش: ه. SSPIHandleCache.cs 42
internal static void CacheCredential(SafeFreeCredentials newHandle) { try { .... } catch (Exception e) { if (!ExceptionCheck.IsFatal(e)) { NetEventSource.Fail(null, "Attempted to throw: {e}"); } } }
خطأ من المقال "
التحقق من الكود المصدري لمكتبات .NET Core باستخدام محلل ثابت PVS-Studio ". السلسلة
"Attempted to throw: {e}" يبدو محرف. نظرًا لحرف
$ المفقود ، فلن يتم استبدال تمثيل سلسلة استثناء
e في السلسلة. نتيجة لذلك ، سيتم استخدام السلسلة "كما هي".
المركز الثالث: "لا يوجد مخرج"
V3008 [CWE-563] تم تعيين متغير "this.linker.s3.region" لقيم مرتين متتاليتين. ربما هذا خطأ. خطوط التحقق: 116 ، 114. AWSSDK.DynamoDBv2.Net45 S3Link.cs 116
public string Region { get { .... } set { if (String.IsNullOrEmpty(value)) { this.linker.s3.region = "us-east-1"; } this.linker.s3.region = value; } }
خطأ من المقال "
البحث عن أخطاء في التعليمات البرمجية المصدر لـ Amazon Web Services SDK لـ .NET ." في جسم الكتلة
if ، تم تخطي
العودة . نتيجة لذلك ،
سيحصل المتغير
this.linker.s3.region دائمًا على
قيمة ، بما في ذلك سلسلة فارغة و
خالية .
المركز الثاني: "كن بالترتيب!"
V3070 يتم استخدام متغير غير مهيأ 'LANG_USER_DEFAULT' عند تهيئة المتغير "LOCALE_USER_DEFAULT". NativeMethods.cs 890
internal static class NativeMethods { .... public static readonly int LOCALE_USER_DEFAULT = MAKELCID(LANG_USER_DEFAULT); public static readonly int LANG_USER_DEFAULT = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); .... }
خطأ من مقالة "
WinForms: أخطاء ، Holmes ". يتم ترتيب ترتيب تهيئة حقول الفصل. لحساب قيمة الحقل
LOCALE_USER_DEFAULT ، استخدم الحقل
LANG_USER_DEFAULT ، الذي لم تتم تهيئته بعد وله قيمة 0. لا يتم استخدام متغير
LANG_USER_DEFAULT في أي مكان آخر في التعليمات البرمجية. لفهم ما الذي يؤدي إليه هذا الخطأ ، تمت كتابة برنامج اختبار يحتوي على طرق من رمز WinForms. للبساطة ، تم استبدال بعض الثوابت الفعلية بقيمها الفعلية:
internal static class NativeMethods { public static readonly int LOCALE_USER_DEFAULT = MAKELCID(LANG_USER_DEFAULT); public static readonly int LANG_USER_DEFAULT = MAKELANGID(0x00, 0x01); public static int MAKELANGID(int primary, int sub) { return ((((ushort)(sub)) << 10) | (ushort)(primary)); } public static int MAKELCID(int lgid) { return MAKELCID(lgid, 0x0); } public static int MAKELCID(int lgid, int sort) { return ((0xFFFF & lgid) | (((0x000f) & sort) << 16)); } } class Program { static void Main() { System.Console.WriteLine(NativeMethods.LOCALE_USER_DEFAULT); } }
كنتيجة للإطلاق ، سيتم عرض ما يلي على وحدة التحكم: 0. سنقوم الآن بتصحيح الخطأ عن طريق تبادل إعلان
الحقول LOCALE_USER_DEFAULT و
LANG_USER_DEFAULT . نتيجة البرنامج في هذا النموذج: 1024.
المركز الأول: "ثق ، لكن تحقق"
مع المقام الأول هو دائما صعبة. يجب أن يكون هناك شيء غير عادي ومثيرة للاهتمام للغاية. في البداية ، اخترت أكثر من عشرين خطأً مثيرًا للاهتمام لهذه المقالة ، ولكن لم يكن هناك شيء يستحق المركز الأول بينها. وبعد ذلك تذكرت مقالة لزميلي سيرجي فاسيلييف ، مكرسة لخطأ واحد. جمال هذا الخطأ هو أنه أثر مباشرة على تشغيل محللنا. كيف؟ هذا واضح بالفعل من عنوان المقال "
تاريخ كيفية العثور على PVS-Studio خطأ في المكتبة المستخدمة في ... PVS-Studio ". مرة أخرى ، لم يتم إلغاء الكسل. :) وهنا أشعر بالخجل تمامًا ولن أعطي وصفًا للخطأ ، لكنني سأقترح اتباع الرابط الخاص بالمقال ومعرفة المزيد. أنا أضمن - الأمر يستحق ذلك. والمقال قصير.
استنتاج
آمل أن تكون الأخطاء مثيرة للاهتمام ، لكن المقال لم يتعب. أذكرك أنه يمكنك دائمًا
تنزيل محلل PVS-Studio للبحث عن الأخطاء في مشاريعك الخاصة ومشروعات الجهات الخارجية بنفسك ، لإرضاء نفسك والأصدقاء والزملاء. واسمحوا يكون هناك أخطاء أقل ، والمزيد من الوقت لتحسين الذات! :)
هل قرأت؟ مبروك على الانتقال إلى المستوى التالي! في المقالات التالية من مدونتنا ،
يتم تسليط الضوء على أفضل الأخطاء لعام 2019 في مشاريع
Java و
C ++ .

إذا كنت ترغب في مشاركة هذه المقالة مع جمهور يتحدث الإنجليزية ، فالرجاء استخدام الرابط الخاص بترجمة: سيرجي خرينوف.
أهم 10 أخطاء تم العثور عليها في مشاريع C # في 2019 .