روش جدید و خلاقانه برای اجرای توابع در جاوا اسکریپت بدون استفاده از پرانتز — Yet another way to invoke functions without parentheses
خلاصه
این مقاله یک ترفند جذاب و غیرمتعارف در جاوا اسکریپت را معرفی میکند که با سوءاستفاده از قابلیت prepareStackTrace شیء Error و دستکاری Prototypeها، امکان اجرای توابع را بدون نوشتن پرانتز فراهم میکند. این تکنیک بیشتر یک چالش فنی جالب است، اما به خوبی پیچیدگیهای عمیق موتورهای جاوا اسکریپت را نشان میدهد.
در دنیای جاوا اسکریپت، روشهای استاندارد و مشخصی برای فراخوانی توابع وجود دارد که استفاده از پرانتز () بارزترین آنهاست. اما گاهی اوقات توسعهدهندگان کنجکاو به سراغ روشهای عجیبوغریب و ساختارشکنی میروند که مرزهای رفتار موتور جاوا اسکریپت را جابهجا میکند. مقاله جدیدی منتشر شده است که روشی تازه برای اجرای توابع دلخواه بدون استفاده از پرانتز را معرفی میکند.
نحوه کارکرد این تکنیک
این پیلود جالب بر اساس سوءاستفاده از مکانیسم ردیابی پشته یا همان prepareStackTrace در شیء Error کار میکند. این قابلیت معمولاً برای فرمتدهی به استک تریس (Stack Trace) استفاده میشود و زمانی که ویژگی stack یک خطا فراخوانی گردد، به صورت خودکار اجرا میشود.
پارامترهای این تابع شامل خود خطا و یک نمایش ساختاریافته از استک است که در واقع آرایهای از موقعیتهای کد محسوب میشود. امضای این تابع با سازنده Function در جاوا اسکریپت همخوانی دارد؛ مشروط بر اینکه آرگومان دوم آن یک کد معتبر جاوا اسکریپت باشد.
چالش اصلی اینجاست که خروجی تولید شده یک استک تریس است و کد معتبر جاوا اسکریپت محسوب نمیشود، بنابراین اجرای مستقیم آن خطای سینتکسی (Syntax Error) ایجاد میکند. برای حل این مشکل، نیاز به کنترل خروجی تابع Array.prototype.toString() داریم تا به جای آرایه، پِیلود دلخواه ما را برگرداند. این کار به دو روش انجام میشود:
- بازنویسی مستقیم آن با یک تابع ثابت که پیلود را برمیگرداند.
- استفاده از تکنیک Prototype Pollution برای تزریق پیلود به یک تابع دیگر و سپس بازنویسی Prototype آرایه.
در نهایت، برای اجرای تابع تولید شده بدون پرانتز، میتوان از ترفند valueOf استفاده کرد. با بازنویسی تابع پیشفرض valueOf در شیء و سپس فراخوانی آن به عنوان یک مقدار اولیه (Primitive)، کد مورد نظر اجرا میشود.
کد نهایی به شکل زیر است که میتوانید آن را در کنسول مرورگر خود امتحان کنید:
Object.prototype.message = 'alert\x281337\x29';
Array.prototype.toString = Error.prototype.toString;
Error.prepareStackTrace = Function;
const x = new Error;
x.valueOf = x.stack;
+x;
نگاه جامعه هکرنیوز
این مقاله در هکرنیوز با استقبال کاربران روبهرو شد و بحثهای جالبی را به همراه داشت:
- برخی کاربران با یادآوری روزهای پیش از ظهور مدلهای زبانی بزرگ (LLM)، از این سبک کدهای خلاقانه و خالص ابراز خوشحالی کردند.
- از نظر فنی، یکی از نکات مهم که توسط کاربران مطرح شد این است که این ترفند روی مرورگر فایرفاکس کار نمیکند؛ زیرا
Error.prepareStackTraceیک API اختیاری است و فقط توسط موتور V8 پیادهسازی شده است. - بحثهای حاشیهای دیگری نیز درباره فلسفه انتقال دادهها در برنامهنویسی و تلاش برای خوانایی کدها از چپ به راست مطرح شد.
چرا این موضوع برای مهندسان اهمیت دارد؟
اگرچه این روش به عنوان یک پترن کاربردی در توسعه نرمافزار توصیه نمیشود، اما بررسی چنین ترفندهایی درک عمیقتری از نحوه کارکرد موتورهای جاوا اسکریپت، مکانیزمهای داخلی مدیریت خطا، و خطرات احتمالی ناشی از Prototype Pollution به توسعهدهندگان میدهد. شناخت این زوایای پنهان به امنیت و طراحی بهینهتر کد کمک میکند.
این مطلب بهصورت کاملاً خودکار و با هوش مصنوعی از مقالهٔ اصلی و بحث هکرنیوز تهیه شده و ممکن است خطا داشته باشد. حقوق مطلب اصلی متعلق به نویسندهٔ آن است. قوانین و گزارش مشکل