الخلاصة

  • أضافت RFC 5229 الأمر set وتوسيع السلاسل ومتغيرات التطابق، لكن استخدامها يتطلب أن يعلن البرنامج النصي صراحةً عن الإمكانية variables.
  • ظلت الذاكرة محدودة: تعتمد القيم الملتقطة على مسار التنفيذ، ولا تظهر إلا داخل البرنامج الجاري، وقد تُقتطع إذا تجاوزت حدود التنفيذ.

احتاج المرشّح إلى ذاكرة صغيرة، لا إلى خادم أكبر

في يناير 2008، كانت وظيفة Sieve محددة: ترشيح الرسائل عند التسليم النهائي. وصفت المواصفة الأساسية لغة مفيدة لكنها مقيدة عمداً؛ فلا متغيرات فيها، ولا حلقات، ولا استدعاء لأوامر الصدفة. لم تكن هذه قائمة وظائف منسية تنتظر أي امتداد ليضيفها. لقد رسمت حدود ما يستطيع مرشّح يكتبه المستخدم أن يطلبه من خادم البريد.

وسّعت RFC 5229 جزءاً صغيراً من تلك الحدود بحذر. يمكن للبرنامج أن يكتب require "variables"، ثم يخزن سلسلة باسم عبر set، ويدرجها في سلسلة أخرى أو يفحص سلسلة أنشأها بنفسه. وإذا نجح تطابق يستخدم المحارف البديلة، أمكن الرجوع إلى النص المطابق كله بالاسم ${0} وإلى الأجزاء الملتقطة بالأسماء ${1} و${2} وما يليهما. وهكذا يستطيع المرشّح أخذ اسم قائمة من ترويسة بريد وإدراجه في مسار صندوق، بدلاً من تكرار النص نفسه في قواعد عدة.

لكن ذلك لا يمنح المرشّح ذاكرة دائمة. تقول المواصفة إن المتغيرات لا تُرى إلا للبرنامج الجاري تنفيذه. ولا تحدد مخزناً مشتركاً لصندوق البريد كله، ولا سجلاً للرسائل السابقة، ولا حالة مشتركة بين المستخدمين. تبدو كلمة «متغير» واسعة، إلا أن الكيان المعياري أضيق: اسم مرتبط بنص ما دام هذا البرنامج يعمل.

الإعلان عن الإمكانية جزء من نموذج السلامة

على البرنامج طلب الإمكانية قبل استخدامها. فمن دون variables لا يتغير تفسير السلاسل ضمناً. وهذا مهم في لغة قابلة للتوسعة: فالميزة لا تعني مجرد عملية جديدة، بل اتفاقاً صريحاً بين البرنامج والمفسّر على أن العملية متاحة.

يحدث التوسيع عند وصول التنفيذ إلى العبارة، مستخدماً القيم السارية آنذاك، ولمرة واحدة فقط. ويصبح المتغير غير المعرّف سلسلة فارغة، كما أن أسماء المتغيرات لا تميّز حالة الأحرف. هذا الاختصار قد يخفي الخطأ: فخطأ مطبعياً في الاسم قد يحذف جزءاً من النص من دون تنبيه واضح إلى غياب القيمة. وإذا احتوت القيمة المدرجة على مرجع آخر من الشكل ${...} فلن يجري توسيعه مرة ثانية على نحو تكراري.

الإضافات بقيت محدودة: تحويل أحرف ASCII إلى الكبيرة أو الصغيرة، وتغيير حالة الحرف الأول، وحماية المحارف البديلة، وحساب طول السلسلة، إضافة إلى اختبار string. لم تضف حساباً أو حلقات أو تنفيذاً لشيفرة اعتباطية. زادت القدرة التعبيرية بمعنى ضيق: تسمية عدد محدود من السلاسل وإعادة استخدامها بطرق محددة، لا إجراء أي حساب ممكن.

قيمة الالتقاط تتوقف على الاختبار الذي نُفذ فعلاً

مع متغيرات التطابق، يصبح مسار التحكم جزءاً من مصدر البيانات. تفرض RFC 5229 تقييم الاختبارات من اليسار إلى اليمين والتوقف متى حُسمت النتيجة المنطقية. في التعبير anyof (true, header :matches ...)، مثلاً، تتحقق النتيجة عند true؛ فلا يُنفذ اختبار الترويسة ولا ينتج قيماً ملتقطة. وقد يحل تطابق ناجح لاحق محل قائمة الالتقاط السابقة، أما الاختبار الفاشل فلا يقدم أجزاء جديدة. لذلك يجب معرفة أي اختبار وصل إليه التنفيذ قبل الاعتماد على ${1} في قاعدة معقدة.

ولا ترث كل أنواع التطابق التي تضيفها امتدادات لاحقة أثر الالتقاط تلقائياً. فقد أوضحت RFC 5173، المنشورة بعد RFC 5229 بثلاثة أشهر، فاصلاً مهماً: عند تفعيل variables تُوسّع مراجع المتغيرات الموجودة في مفاتيح اختبار body، لكن التطابق بالمحارف البديلة في ذلك الاختبار لا يجوز أن يملأ متغيرات الالتقاط. تسمح المواصفات بتركيب بعض الإمكانات، لكنها لا تسوّي بين عمليات تبدو متشابهة.

وتجعل الحدود الدنيا هذا التقييد ملموساً. كان على التنفيذ دعم 128 متغيراً على الأقل، وأسماء بطول 32 حرفاً على الأقل، وقيم بطول 4,000 حرف على الأقل، ومتغيرات الالتقاط ${1} حتى ${9}. وإذا تجاوزت قيمة ما قدرة تنفيذ بعينه، فالأفضل اكتشاف ذلك عند التجميع إن أمكن؛ أما إن لم يظهر إلا أثناء التشغيل، فيُتوقع اقتطاعها ولا ينبغي اعتباره خطأ. ولهذا تحذر اعتبارات الأمن من وضع تراكيب كبيرة أو مهمة أمنياً في المتغيرات، وتذكّر بأن المرسل يستطيع التحكم بالنص الملتقط.

طول تاريخ المسودات لا يثبت انتشار الميزة

يعود سجل Datatracker إلى مسودات فردية بدأت في مارس 2003، ثم إلى نسخ مجموعة عمل Sieve منذ أواخر 2004، مع مراجعات متعددة خلال 2005. ويعرّف تقرير IESG الوثيقة بأنها نتاج مجموعة عمل Sieve Mail Filtering Language. أما الموافقة في 2006 ونشر RFC 5229 في يناير 2008 فهما محطتان منفصلتان في السجل. لا تفسر هذه التواريخ سبب طول العملية ولا تكشف عدد الخوادم التي اعتمدت الامتداد.

تتيح ملاحظة Heng Lu عن «Minimum Initial Specification» زاوية تحليلية هنا: فتعليمة require تسمح لقاعدة أساسية صغيرة بالتعايش مع إمكانات مستقبلية يفعّلها كل برنامج على حدة. وتذكّر «Running-Code Primacy» بأن نشر الإمكانية في معيار لا يثبت أن خادماً بعينه ينفذها أو يتيحها. أما تحليل «Reality Layers» فيفصل بين ما يعلنه البرنامج، وحالة المفسّر، وسلوك الخادم، وما يراه المستخدم أخيراً في صندوقه. هذه أطر تحليلية لاحقة، وليست دليلاً على نية مؤلفي RFC.

صار بوسع المرشّح تذكّر ما التقطه تطابق واحد وإعادة استخدام بعض السلاسل المسماة. لكن ذلك لا يثبت وحده أنه احتفظ بمحادثة سابقة، أو تحقق من هوية المرسل، أو عرف أين انتهت الرسالة. والتغيير التاريخي في RFC 5229 لم يكن محو حدود Sieve، بل جعل وصلة صغيرة ومعلنة أكثر نفعاً.

المصادر