לדלג לתוכן

פרויקט עטיפה בטוחה לספריית זיכרון זרה

בפרויקט הזה נבנה ספריית סי קטנה שמחזיקה עותק בלתי משתנה של באפר, ונעטוף אותה בממשק ראסט בטוח. המטרה אינה לחסוך את Vec, אלא להוכיח שהבעלות, החיים והמקצה נשארים נכונים כאשר השפות אינן חולקות מערכת טיפוסים.

הספרייה תחשוף ארבע פעולות: יצירה מעותק של טווח בייטים, קבלת מצביע לנתונים, קבלת אורך והשמדה. המצביע יישאר תקף עד השמדת הידית, והספרייה לא תציע שינוי של הנתונים לאחר היצירה. הידית תהיה אטומה למשתמש בראסט, והעטיפה לא תחשוף דרך בטוחה לשחזר אותה מכתובת שרירותית.

כתבו טיפוס ForeignBytes עם בנאי שמחזיר שגיאה בכשל הקצאה, מתודה as_slice שמחזירה פרוסה הקשורה לחיי self, ומימוש Drop שמשתמש במשחרר של הספרייה. החליטו במפורש אם הטיפוס מותר להעברה בין תהליכונים, ובשלב הזה חסמו זאת עד שיהיה חוזה שנבדק בפרק השביעי.

בדקו באפר ריק, בייט אפס באמצע, אורך גדול יחסית וכמה ידיות עצמאיות. הוסיפו בצד סי מונה אבחוני של ידיות חיות עבור הבדיקות בלבד, והוכיחו שבסיום scope רגיל ובחזרה מוקדמת מספר היצירות המוצלחות שווה למספר ההשמדות. הוסיפו בדיקת קומפילציה שלילית שמנסה לשמור פרוסה לאחר שהידית הושמדה.

הגישו את כותרת הסי, המימוש, העטיפה, בדיקות, פקודות בנייה ומסמך קצר של אינווריאנטים. לכל unsafe רשמו מי מבטיח שהמצביע תקף, מי רשאי לשנות את הזיכרון ומי משחרר אותו. אל תסתפקו בהערה שהקוד נבדק.

תנאי הסיום הוא שכל הקלטים המוגדרים מקבלים תוצאה נכונה, אין דרך בטוחה לייצר שתי בעלויות על אותה ידית, הפרוסה אינה יכולה לברוח מחיי הידית, וכשל יצירה אינו מפעיל השמדה על מצביע null. בדקו את קוד הסי עם sanitizer אם סביבת הבנייה שלכם תומכת בכך, וציינו בנפרד מה נבדק בקומפילציה ומה הורץ.