أهم 10 أخطاء تم العثور عليها في مشاريع C # في 2019

الصورة 1

مرحبا لجميع عشاق البق! سيأتي العام الجديد قريبًا ، لذلك حان الوقت لتقييم السنة المنتهية ولايتها. من الناحية التقليدية ، يسعدنا تقديم قائمة الأخطاء التي وجدها فريق 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, // <= isFirstDisplayedColumn); // <= .... } 

الخطأ من مقالة " WinForms: أخطاء ، هولمز ". يشير المحلل إلى أنه عندما يتم خلط الوسيطتين الأخيرتين للطريقة. لنلقِ نظرة على إعلان AdjustCellBorderStyle :

 public virtual DataGridViewAdvancedBorderStyle AdjustCellBorderStyle( DataGridViewAdvancedBorderStyledataGridViewAdvancedBorderStyleInput, DataGridViewAdvancedBorderStyle dataGridViewAdvancedBorderStylePlaceholder, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow) { .... } 

يبدو أن المحلل هو الصحيح. غالبًا ما يقوم المطورون بتمرير بعض الوسائط بترتيب عكسي ، على سبيل المثال ، للتبديل حول المتغيرات. ولكن لا يبدو أن هذا هو الحال. أولاً ، يتم خلط متغيرات نوع bool . ثانياً ، لا توجد أسماء طرق غير عادية: لا يوجد "تبديل" أو "عكس". علاوة على ذلك ، ليس من الصعب ارتكاب خطأ مثل هذا: فالناس ينظرون بشكل مختلف إلى ترتيب ترتيب "السطر / العمود".

المركز التاسع "قريب جدًا من الخلود"


V3110 العودية المحتملة لانهائية داخل طريقة 'TryValidateModel'. PrefixedModuleUpdater.cs 48

 public bool TryValidateModel(object model, string prefix) { return TryValidateModel(model, Prefix(prefix)); } 

الخطأ من المقال " مسح رمز Orchard CMS for Bugs ". كان هناك خطأ أدى إلى العودية لانهائية. لفهم الطريقة التي تم بها ارتكاب الخطأ ، يجب على المرء مراعاة التحميل الزائد لأسلوب 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"; // <= public const string Recurse = "Recursively list the children of the management group"; public const string ParentId = "Parent Id of the management group"; public const string GroupName = "Management Group Id"; // <= public const string DisplayName = "Display Name of the management group"; public const string Expand = "Expand the output to list the children of the management group"; public const string Force = "Force the action and skip confirmations"; public const string InputObject = "Input Object from the Get call"; public const string ParentObject = "Parent Object"; } 

الخطأ من مقالة " أزور 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; // nothing to remove. } .... 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 ". غاب عن العودة في جسم كتلة إذا . نتيجةً لذلك ، سيحصل المتغير 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: أخطاء ، هولمز ". يتم ترتيب ترتيب التهيئة لحقول الفئة. لحساب قيمة الحقل LOCALE_USER_DEFAULT ، يتم استخدام حقل LANG_USER_DEFAULT ، والذي لم تتم تهيئته بعد في الوقت الحالي وهو 0. لا يتم استخدام المتغير في أي مكان آخر في التعليمات البرمجية. للحصول على ما يؤدي إليه هذا الخطأ ، تمت كتابة برنامج اختبار كامل يحتوي على أساليب من رمز 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 للعثور على الأخطاء في مشاريعك والجهات الخارجية لإرضاء نفسك أو زملائك أو أي Tom أو Dick أو Harry. دع الأخطاء تكون أقل ووقتًا لتحسين الذات - أكثر! :)

هل قرأت حتى النهاية؟ تهاني على الوصول إلى المستوى الجديد! لا تفوت مقالات upcomimg في مدونتنا - أفضل الأخطاء في مشاريع Java و C ++ التي تم العثور عليها في عام 2019.

الصورة 2

Source: https://habr.com/ru/post/ar481174/


All Articles