ทำให้ภาษาของคุณใช้ไม่ได้


191

ลองเขียนโค้ดในภาษาของคุณและทำให้มันไม่เป็นไปตามเกณฑ์ของเราในการเป็นภาษาโปรแกรมอีกต่อไป

ภาษาเป็นไปตามเกณฑ์ของเรา (เวอร์ชั่นง่ายสำหรับความท้าทายนี้) ในการเป็นภาษาโปรแกรมหาก:

  • มันสามารถอ่านอินพุตของผู้ใช้ที่แสดงถึง tuples ของจำนวนเต็มบวกในบางวิธี
  • สามารถส่งออกผลลัพธ์ที่แตกต่างกันอย่างน้อยสองรายการขึ้นอยู่กับอินพุต
  • มันสามารถใช้จำนวนเต็มบวกสองจำนวนแล้วบวกเข้าไป (และผลลัพธ์อาจมีผลต่อเอาต์พุต)
  • มันสามารถใช้จำนวนเต็มบวกและตัดสินใจว่ามันเป็นนายก (และผลที่สามารถส่งผลกระทบต่อการส่งออก)
  • สำหรับวัตถุประสงค์ของการท้าทายนี้ชนิดของการส่งออกใด ๆ ที่ไม่ได้เป็นวิธีการส่งออกได้รับอนุญาตให้เป็นความท้าทายที่ปกติจะถูกละเว้น ดังนั้นไม่สำคัญว่าโปรแกรมจะสามารถเล่นเพลงหรือโพสต์ผ่าน HTTP ฯลฯ ได้หรือไม่
  • อัปเดต:คุณยังสามารถเลือกวิธีการส่งออกหนึ่งหรือบางวิธีและละเว้นวิธีอื่น ๆ ได้ แต่คุณต้องใช้คำจำกัดความเดียวกันทุกที่ในเกณฑ์ต่อไปนี้ และหากโปรแกรมของคุณสามารถปิดใช้งานมากกว่าหนึ่งวิธีการส่งออก - ที่คุ้มค่า upvotes มากขึ้น

ตัวอย่างเช่นทำให้ไม่สามารถส่งออกหรือปิดใช้งานการวนซ้ำทั้งหมดดังนั้นจึงไม่สามารถทำการทดสอบแบบดั้งเดิมและทำให้แน่ใจว่าผู้ใช้ไม่สามารถเปิดใช้งานได้อีกครั้ง

คุณควรออกจากที่สำหรับใส่รหัสใหม่ โดยค่าเริ่มต้นจะอยู่ท้ายรหัสของคุณ หากเราพิจารณาวางซอร์สโค้ดในที่นั้นในคำตอบของคุณและเรียกใช้รหัสเต็มเป็นโปรแกรมที่สมบูรณ์เป็นล่ามของภาษาใหม่ภาษานั้นไม่ควรเป็นไปตามเกณฑ์

แต่ใส่รหัสจะต้องดำเนินการในลักษณะเช่นภาษาที่น่าพอใจเกณฑ์ไปนี้:

  • รหัสที่แทรกจะต้องเป็นไวยากรณ์เหมือนกับบางสิ่งบางอย่าง (กล่าวคือบล็อกโค้ดในเกณฑ์ต่อไปนี้) ซึ่งโดยทั่วไปแล้วจะเป็นไปตามเกณฑ์จากมุมมองของผู้ที่ต้องการเขียนปากกาเน้นข้อความ ดังนั้นจึงไม่สามารถอยู่ในสตริงความคิดเห็น ฯลฯ
  • รหัสที่แทรกจะต้องถูกดำเนินการจริงตามที่ควรจะเป็นไปตามเกณฑ์ ดังนั้นมันจึงไม่สามารถอยู่ในฟังก์ชั่นที่ไม่ได้ใช้งานหรือsizeofใน C คุณไม่สามารถดำเนินการได้เฉพาะส่วนที่ไม่สามารถใช้งานได้ในโค้ดและคุณไม่สามารถใส่มันหลังจากวนซ้ำไม่สิ้นสุดเป็นต้น
  • คุณไม่สามารถ จำกัด จำนวนโปรแกรมที่ถูกต้องทางไวยากรณ์ที่เป็นไปได้ที่สร้างขึ้นด้วยวิธีนี้ หากมีบางอย่างที่เหมือนขีดจำกัดความยาวในภาษาที่คุณใช้อยู่ก็ไม่ควรเป็นไปตามเกณฑ์แม้ว่าข้อ จำกัด นี้จะถูกลบออกไป
  • คุณไม่สามารถแก้ไขหรือ "ใช้" เนื้อหาของอินพุต / เอาต์พุตได้ แต่คุณสามารถป้องกันไม่ให้เข้าถึงได้
  • เกณฑ์เหล่านี้มักใช้กับภาษาที่ไม่มี I / O อย่างชัดเจน:
    • รหัสของคุณควรเปลี่ยนเส้นทางการป้อนข้อมูลของผู้ใช้ (ที่มีข้อมูลความยาวตามอำเภอใจ) ไปยังรหัสที่แทรกหากบล็อกรหัสไม่สามารถรับข้อมูลผู้ใช้โดยตรง / ชัดเจนในภาษาที่คุณใช้
    • รหัสของคุณควรพิมพ์ค่าที่ส่งคืนของรหัสที่แทรกหากบล็อกรหัสมักไม่สามารถส่งออกข้อมูลโดยตรง / อย่างชัดเจนในภาษาที่คุณใช้
    • ในกรณีที่คุณพิมพ์ค่าที่ส่งคืนและพิมพ์ในภาษาที่คุณใช้ประเภทที่ส่งคืนควรจะมีค่าที่เป็นไปได้ 2 แบบที่แตกต่างกัน ตัวอย่างเช่นคุณไม่สามารถใช้ชนิดstruct {}หรือstruct {private:int x;}ใน C ++

นี่คือการประกวดความนิยม คำตอบที่ถูกต้องได้รับการโหวตสูงสุด(ดังนั้นไม่มีใครเห็นข้อผิดพลาดหรือข้อผิดพลาดทั้งหมดได้รับการแก้ไข) ชนะ

ชี้แจง

  • คุณไม่ควรแก้ไขรหัสในรูปแบบข้อความ แต่สามารถเปลี่ยนไวยากรณ์ก่อนที่รหัสจะถูกตีความหรือรวบรวม
  • คุณสามารถทำสิ่งอื่น ๆ ในขณะที่รหัสกำลังทำงานอยู่ แต่เหตุผลที่มันไม่เป็นไปตามเกณฑ์ที่ควรจะอยู่ในตัวแทรกรหัส อาจเกิดข้อผิดพลาดเนื่องจากการรบกวนของเธรดอื่น แต่ไม่เพียง แต่ถูกเธรดอื่นฆ่า
  • รายละเอียดทั้งหมดโดยทั่วไปหมายถึงมันควรจะเป็นไปตามหลักไวยากรณ์ตามเกณฑ์ที่น่าพอใจหากบิวด์อินทั้งหมดไม่เปลี่ยนแปลงแต่ไม่ได้ทำจริง ไม่เป็นไรถ้าคุณพบวิธีแก้ปัญหาที่ไม่ใช่ทางไวยากรณ์เช่นการส่งพารามิเตอร์ไปยังการบล็อกโค้ดอย่างถูกต้อง แต่ทำให้ไม่สามารถใช้งานได้ในบางวิธี
  • อีกครั้งรหัสที่แทรกจะต้องดำเนินการจริง รหัสหลังจากที่วง จำกัดหรือcrashingถือว่า "ไม่ดำเนินการจริง" จึงไม่ถูกต้อง คำตอบเหล่านั้นอาจน่าสนใจ แต่มีคำถามวนซ้ำไม่สิ้นสุดหรือคำถามหยุดทำงานในไซต์นี้และคุณอาจพบคำตอบที่เหมาะสมกว่า ถ้าไม่ใช่ให้ลองถามคำถามใหม่ ตัวอย่างของคำถามเหล่านั้นคือ:

ลีดเดอร์บอร์ด

var QUESTION_ID=61115/*,OVERRIDE_USER=8478*/;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,/*getComments()*/(more_answers?getAnswers():process())}})}/*function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}*/function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),score:s.score,language:a[1],lang:jQuery('<div>').html(a[1]).text(),link:s.share_link})}),e.sort(function(e,s){var r=e.score,a=s.score;return a-r});var s={},r=1,a=null,n=1;e.forEach(function(e){e.score!=a&&(n=r),a=e.score,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",e.n=n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.score).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text())/*,s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}*/});var t=e/*[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o])*/;t.sort(function(e,s){return (e.lang.toUpperCase()>s.lang.toUpperCase())-(e.lang.toUpperCase()<s.lang.toUpperCase())||(e.lang>s.lang)-(e.lang<s.lang)});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{PLACE}}",o.n).replace("{{LANGUAGE}}",o.language).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.score).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<(?:h\d|(?!.*<h\d>)p)>\s*((?:[^,;(\s]| +[^-,;(\s])+)(?=(?: *(?:[,;(]| -).*?)?\s*<\/(h\d|p)>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;float:left}table{width:250px}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/all.css?v=7509797c03ea"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Score</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Sorted by Language</h2> <table class="language-list"> <thead> <tr><td></td><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{PLACE}}</td><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>


ฉันได้รับอนุญาตให้เปลี่ยนรหัสก่อนดำเนินการหรือไม่ นอกจากนี้ฉันสามารถเรียกใช้รหัสอื่นในขณะที่ฉันกำลังเรียกใช้รหัสที่กำหนดได้หรือไม่
Blue

21
นี่อาจทำให้ตำรวจและโจรที่ยิ่งใหญ่ท้าทายฉันอย่างที่คิด
DankMemes

6
@DankMemes เห็นด้วย มันชัดเจนมากเกินไปและคำตอบส่วนใหญ่จะถูกทำให้เป็นโมฆะโดยการหาวิธีแก้ปัญหา CnR กับหลักฐานนี้จะมีความสุข
Mego

3
ดังนั้นจึงดูเหมือนว่าจะพูดว่าในภาษาที่มี IO ชัดเจนมันอนุญาตให้ทำสิ่งที่น่าเบื่ออย่างสมบูรณ์เช่นการอ่านและการละทิ้งเนื้อหาของ stdin มันตั้งค่าสนามเด็กเล่นที่ไม่ยุติธรรมอย่างสมบูรณ์ซึ่งบางภาษาต้องการให้คุณจัดการกับ IO สำหรับรหัสที่แทรกอย่างระมัดระวังและภาษาอื่น ๆ ช่วยให้คุณสามารถทิ้งมันและปฏิเสธ IO กับรหัสที่แทรก
ปีเตอร์เทย์เลอร์

1
เราได้รับอนุญาตให้ใช้ภาษาที่ไม่สามารถเริ่มต้นได้หรือไม่ (ตัวอย่างเช่น JavaScript)
12Me21

คำตอบ:


319

JavaScript Shell

สิ่งนี้จะทำให้ภาษาใช้ไม่ได้อย่างสมบูรณ์

clear(this);

มันไม่ดีเลยใช่ไหมที่ JavaScript มีฟังก์ชั่นที่ดีในการทำลายตัวมันเอง?


มันค่อนข้างง่ายclearฟังก์ชั่นจะทำให้วัตถุว่างเปล่าอย่างสมบูรณ์ thisอ้างถึงวัตถุทั่วโลกล้างออกทุกอย่างรวมถึงตัวสร้างและฟังก์ชั่น


เพราะสิ่งนี้จะล้างข้อมูลทุกอย่างทำอะไรแม้แต่กำหนดตัวอักษรจะทำให้เกิดข้อผิดพลาดทำให้ภาษาไร้ประโยชน์อย่างสมบูรณ์: * ไม่จำเป็นต้องใช้สภาพแวดล้อม REPL ใช้โปรแกรมSpiderMonkey (ไม่ใช่เชลล์เบราว์เซอร์) ซึ่งเป็นเอ็นจิน JS ดั้งเดิมตัวอย่างการใช้งาน


4
ที่clearฟังก์ชั่นน่าจะเป็นนอกจากแมงมุมเปลือกเฉพาะไม่ได้เป็นสิ่ง JavaScript ทั่วไป แน่นอนมันไม่ปรากฏในES5 spec §คุณสมบัติฟังก์ชั่นของวัตถุทั่วโลก ฉันลองด้วยnodeและได้รับ "ReferenceError: clear is not define" ในคอนโซลของ Chrome และ Firefox clearฟังก์ชันจะล้างคอนโซลโดยไม่คำนึงถึงว่ามีการโต้แย้งอะไร หรือบางทีเครื่องมือที่คุณใช้เป็นไปตามรุ่นของ ECMAScript ที่เก่ากว่า 5.1
Anko

2
คุณสามารถแก้ไขคำแถลง“ มันดีกว่าที่ JavaScript มีฟังก์ชั่นที่ดีเพื่อทำลายตัวเองหรือไม่” JavaScript ไม่มีฟังก์ชันนั้นมีเพียงการใช้งาน SpiderMonkey เท่านั้น
Anko

1
@Anko SpiderMonkey เป็น JavaScript แต่มาพร้อมกับ Firefox (SpiderMonkey เป็นเครื่องมือ JS ของ Firefox) ฉันจะเขียนเวอร์ชันสำหรับ node.js ฯลฯ ในภายหลังเมื่อฉันมีเวลา
Downgoat

6
ฉันคิดว่าคุณสับสนJavaScript (ภาษา) กับSpiderMonkey (หนึ่งในการนำภาษาไปใช้มากมาย) ชาดกสุดขีด: ในขณะที่ฉันสามารถเขียนการใช้งาน C อย่างบ้าคลั่งซึ่งการร้องขอทั้งหมดของพฤติกรรมที่ไม่ได้กำหนดส่งผลให้เกิดการพิมพ์ข้อความเต็มรูปแบบของปฏิญญาสากลว่าด้วยสิทธิมนุษยชนฉันอาจจะไม่สามารถยืนยันได้ว่า "ที่เพิ่งระบุตัวชี้ null เป็นโซลูชัน C ที่ถูกต้อง :)
Anko

8
@Anko ตามกฎของไซต์ภาษาจะถูกกำหนดโดยการนำไปใช้ หากคำตอบทำงานอย่างสม่ำเสมอในการใช้งานอย่างน้อยหนึ่งครั้งที่เผยแพร่ก่อนคำถามนั้นก็เป็นที่ยอมรับ ดูที่นี่และที่นี่ (ดังนั้นรหัสจึงถูกต้อง แต่ฉันจะไม่แสดงความคิดเห็นในถ้อยคำเฉพาะนั้น)
jimmy23013

169

Emmental

;#33!

ฉันรู้ว่านี่ไม่ใช่รหัสกอล์ฟ แต่เป็นเครื่องมือที่เหมาะสมสำหรับงานคุณรู้ไหม ...

!รหัสผู้ใช้สามารถแทรกหลัง

Emmental เป็น esolang ที่น่าสนใจซึ่งมีพื้นฐานจากการเขียนล่ามใหม่ สัญลักษณ์เดี่ยวทุกตัว (รวมถึงสัญลักษณ์ในตัว) สามารถนิยามใหม่เป็นโปรแกรม Emmental ตามอำเภอใจ ภาษาอาศัยคุณลักษณะนี้มากจนไม่มีโครงสร้างลูปใด ๆ แต่คุณกำหนดคำสั่งซ้ำซึ่งปรากฏในคำจำกัดความของตนเอง

นิยามใหม่นี้เกิดขึ้นผ่านทางซึ่งอ่านอักขระจากสแต็คแล้วอ่านสตริงจากสแต็คจนกว่าจะพบ! ;จากนั้นอักขระจะถูกนิยามใหม่เพื่อหมายถึงโปรแกรมที่แสดงโดยสตริงนั้น

นั่นหมายความว่าเราสามารถปิดใช้งานคุณสมบัติการวนซ้ำของ Emmental ได้โดยการกำหนด! ตัวเองใหม่เป็นโปรแกรมเปล่า ในขณะที่โค้ด Emmental อื่น ๆ ยังคงทำงานได้อย่างสมบูรณ์แบบและเกณฑ์ของภาษาการเขียนโปรแกรมยังคงเป็นจริง แต่ก็เป็นไปไม่ได้ที่จะกำหนดสัญลักษณ์อีกต่อไป หากไม่มีฟีเจอร์นี้ (และไม่สามารถวนซ้ำได้) Emmental จะไม่สามารถทดสอบได้ว่าหมายเลขนั้นจะเป็นจำนวนเฉพาะหรือไม่


49
ปิดการใช้งานคุณสมบัติการกำหนดเดียวของภาษา: อัจฉริยะบริสุทธิ์ นี่เป็นเครื่องมือที่เหมาะสมสำหรับงาน +1
ETHproductions

93

PHP

หนึ่งสามารถฆ่า PHP โดยการตั้งค่าขีด จำกัด ของหน่วยความจำเป็น 1

มันจะตายอย่างสมบูรณ์

ลองสิ่งนี้:

<?php
    ini_set('memory_limit',1);

    //code here

สิ่งนี้ไม่ควรเกิดข้อผิดพลาดเนื่องจากไม่มีหน่วยความจำเพียงพอสำหรับสิ่งนั้น

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับmemory_limitคำสั่ง


หากอันก่อนหน้านี้ไม่ถูกต้องใครสามารถใช้บัฟเฟอร์เอาต์พุต:

<?php
    ob_start();

    //code here

    ob_clear();

สิ่งนี้จะลบเอาต์พุตทั้งหมดอย่างสมบูรณ์ เนื่องจากบัฟเฟอร์เอาต์พุตยังคงเปิดอยู่สิ่งอื่นที่เหลือโดยไม่ตั้งใจหลังจากรหัสจะไม่แสดงเช่นกัน


ใช้แนวคิดของ@fschmengler :

<?php
    define('OB_START_LEVEL', ob_get_level());
    ob_start(function(){return'';}, -1, PHP_OUTPUT_HANDLER_CLEANABLE);
    //or, for PHP <5.3:
    //ob_start(create_function('','return"";'), -1, PHP_OUTPUT_HANDLER_CLEANABLE);

    //code here

    while(ob_get_level() > OB_START_LEVEL) ob_clear();

สิ่งนี้จะหลีกเลี่ยงปัญหาการลบบัฟเฟอร์เอาต์พุตที่เริ่มโดยอัตโนมัติซึ่งใช้เพื่อจับเอาต์พุตที่จะถูกบีบอัด

นอกจากนี้ยังป้องกันไม่ให้บัฟเฟอร์เอาต์พุตถูกลบหรือล้างออก (ส่งไปยังเบราว์เซอร์) หากต้องการ inforce ใหม่จะมีการเพิ่มตัวจัดการเอาต์พุตซึ่งจะส่งคืนสตริงว่างเสมอ
การทำงานob_end_flush(); echo "Hello, world!";จะไม่ผลิตอะไร ob_start();แต่จะส่งออกไปกับธรรมดา

ขอบคุณ@LucasTrzesniewskiสำหรับการเปิดเผยปัญหานี้!


1
เนื่องจากคุณสามารถมีระดับการบัฟเฟอร์เอาต์พุตได้ระดับที่สองจึงไม่ทำงาน บ่อยครั้งที่while(ob_get_level()) ob_end_flush();ใช้ในเฟรมเวิร์กเพื่อล้างบัฟเฟอร์เอาต์พุตทั้งหมดที่อาจเปิดทิ้งไว้โดยไม่ตั้งใจ
Fabian Schmengler

@fschmengler ที่จะทำให้เกิดปัญหากับบัฟเฟอร์ส่งออกที่เปิดโดยอัตโนมัติมักจะใช้ในการบีบอัดเอาท์พุทโดยใช้ gzip ซึ่งในทางกลับกันก็จะเอาชนะวัตถุประสงค์
Ismael Miguel

สิ่งนี้สามารถเลี่ยงได้ด้วย:ob_end_flush(); echo "Hello, world!";
Lucas Trzesniewski

8
เหตุใดฉันจึงไม่แปลกใจที่ PHP จบลงไปทางด้านบนของคะแนนกราฟ :)
MonkeyZeus

47
This shouldn't even throw any error, since there isn't enough memory for that.LOL'ed at :) :)
ETHproductions

91

รหัสเครื่อง x86 ในโหมดจริง (=> เกือบทุกโปรแกรม DOS)

00000000  6a 00 07 b9 00 04 30 c0  31 ff f3 aa              |j.....0.1...|
0000000c

กล่าวคือ

push 0
pop es
mov cx,400h
xor al,al
xor di,di
rep stosb

ฉันหวังว่าคุณจะไม่ยึดติดกับโต๊ะขัดจังหวะของคุณมากเกินไป


75
เซอร์ถ้าผมอาจจะไปขัดจังหวะคุณไม่กี่รอบดังนั้นฉันอาจ Fini ....
การส่องสว่าง

6
แล้วถ้าหากคำสั่งแรกของรหัสที่ฉันใส่เข้าไปคืออะไรcliจากนั้นฉันจะแก้ไขตารางขัดจังหวะและทำการคำนวณเฉพาะช่วง ฯลฯ ?
Nate Eldredge

3
@NateEldredge: ขั้นตอนต่อไปคือการจำคุกส่วนที่เหลือของรหัสเพื่อโทร 3 โดยไม่มีแทรมโพลีนกลับไปที่แหวน 0; ฉันจะดูว่าฉันจัดการที่จะรวบรวมตัวอย่างการทำงาน (ความเป็นไปได้อีกอย่างคือการสแกนพื้นที่ที่อยู่ทั้งหมดและ NOP-out ทั้งหมดcli( inpและoutpเพียงเพื่อการวัดที่ดี) แต่ฉันไม่รู้ว่าจะอนุญาตหรือไม่ ตามกฎ
มัตเตโออิตาเลีย

2
อย่างน้อยที่สุดมันจะไม่หยุดโปรแกรมจากการเขียนโดยตรงไปยังบัฟเฟอร์หน้าจอ (ซึ่งเป็นเรื่องปกติใน DOS)
Jerry Coffin

1
@NateEldredge: กฎไม่ชัดเจนเกี่ยวกับเรื่องนี้และถ้าคุณมองไปรอบ ๆ คำตอบส่วนใหญ่จะรวมอยู่ในการแก้ไขสภาพแวดล้อมที่สร้างข้อผิดพลาดรันไทม์บางประเภทตามคำแนะนำเล็กน้อย (JS clear(this);, ขีด จำกัด หน่วยความจำใน PHP, การเรียกซ้ำ ขีด จำกัด ใน Python สภาพแวดล้อมแบบ sandbox ใน Python และอื่น ๆ อีกมากมาย) ฉันไม่เห็นว่านี่เป็นปัญหา
Matteo Italia

68

ชวา

import java.io.*;
import java.lang.reflect.*;
public class Test2 {
    public static void main(String[] args) throws Exception {
        args = new String[0];
        System.setOut(new PrintStream(new ByteArrayOutputStream()));
        System.setErr(new PrintStream(new ByteArrayOutputStream()));
        System.setIn(new ByteArrayInputStream(new byte[0]));

        Field modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);

        Class<?> fdClass = java.io.FileDescriptor.class;
        Field outField = fdClass.getDeclaredField("out");
        outField.setAccessible(true);
        modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
        outField.set(null, new FileDescriptor());
        Field errField = fdClass.getDeclaredField("err");
        errField.setAccessible(true);
        modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
        errField.set(null, new FileDescriptor());
        Field inField = fdClass.getDeclaredField("in");
        inField.setAccessible(true);
        modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);
        inField.set(null, new FileDescriptor());

        System.setSecurityManager(new SecurityManager(){
            private boolean exitAllowed = false;
            public void checkPermission(java.security.Permission perm) {
                String name = perm.getName();
                if(name.equals("setIO")
                        || name.equals("setSecurityManager")
                        || name.equals("writeFileDescriptor")
                        || name.equals("readFileDescriptor")
                        || name.equals("suppressAccessChecks")
                        || (perm instanceof FilePermission
                            && name.startsWith("/proc/self/fd/"))){
                    throw new SecurityException("Nope");
                }
                if(name.startsWith("exitVM") && !exitAllowed){
                    exitAllowed = true;
                    System.exit(0);
                }
            }
            public void checkExec(String cmd){
                throw new SecurityException("nope");
            }
        });

        // program here
    }
}

แก้ไข: ตอบโต้กำลังทำให้ยักษ์นี้ :(

เปลี่ยนทิศทาง stdin และ stdout ไปเป็นสตรีม null และแทนที่ args ด้วยอาร์เรย์ว่าง นอกจากนี้ยังใช้แฮ็กการสะท้อนจำนวนมหาศาลเพื่อให้แน่ใจว่า IO มาตรฐานนั้นถูกซ่อนอยู่อย่างแท้จริง ในที่สุดก็กำหนดผู้จัดการความปลอดภัยเพื่อให้แน่ใจว่ามาตรฐาน IO ไม่สามารถสร้างขึ้นใหม่และทำให้แน่ใจว่าโปรแกรมไม่สามารถตั้งรหัสออก




10
+1 โดยส่วนตัวแล้วฉันไม่คิดว่าวิธีแก้ปัญหา / proc เป็นตัวแบ่งข้อตกลงจริงเพราะฉันไม่ได้ใช้ Linux และ Unix OS ของฉันไม่ใช่ Windows OS ของฉันที่มีระบบไฟล์ / proc
Jerry Jeremiah

67
สรุปความท้าทายนี้: 1. JavaScript, 12 ตัวอักษร 2. Emmental, 6 ตัวอักษร 3. x86, 12 ไบต์ 4. Python 42 ตัวอักษร 5. Java, 2264 ตัวอักษร ! ทำไมฉันไม่แปลกใจ
หยุดที่จะเปลี่ยนรหัสลับเมื่อ

34
@ceasedtoturncounterclockwis เป็นเพราะ java มีความปลอดภัยมากกว่าดังนั้นจึงเป็นการยากที่จะทำลาย: D
Pierre Arlaud

62

Lua

_ENV=""

ใน Lua _ENVคือสภาพแวดล้อมที่ตัวแปรส่วนกลางฟังก์ชันตาราง ฯลฯ ถูกเก็บไว้การกำหนดให้เป็นสตริงว่างเปล่าหมายความว่าคุณไม่สามารถกำหนดสิ่งใหม่ได้และฟังก์ชันและตัวแปรทั้งหมดจะถูกลบทิ้ง ซึ่งหมายความว่าคุณไม่สามารถส่งออกอะไรนำเข้าหรือทำอะไรได้เลย


1
ไม่_ENV=5ทำงาน? ถ้าเป็นเช่นนั้นมันจะสั้นกว่าหนึ่งตัวอักษร
Immibis

7
@immibis True แต่นี่คือการประกวดความนิยมไม่ใช่การประกวดความยาวรหัส ป.ล. - ให้คุณเชื่อมั่นในคำตอบของลัวะ
Pharap

+1 สำหรับ Lua $ _G = nil $ ไม่เหมือนกันเช่นกันใช่หรือไม่
Doddy

@Doddy Nope เนื่องจาก _G เป็นเพียงสำเนาของ _ENV คุณสามารถใช้เพื่อค้นหาตัวแปรและสิ่งต่าง ๆ เช่นนั้น - มันไม่ใช่สภาพแวดล้อมจริง ๆ อย่างไรก็ตามคุณสามารถทำได้ _G = nil จากนั้นตั้งค่าสภาพแวดล้อมเป็น _G และนั่นจะมีผลเช่นเดียวกัน
TreFox

ไม่จริงทั้งหมด หากคุณมีข้อมูลสำรองอยู่ที่ไหนสักแห่งในตัวแปรโลคัลคุณสามารถเรียกคืนได้ และคุณยังสามารถกำหนดตัวแปรท้องถิ่นและแม้แต่เรียกใช้ฟังก์ชันที่เกี่ยวข้องกับสตริงได้!
Val

46

ภาษาของเช็คสเปียร์

Have Fun Mr Parser.

Romeo, a young man of Verona.
Juliet, a young lady of Verona.
Hamlet, another character which causes the crash.

Act I
Scene I The crash.

[Enter Romeo]
[Enter Juliet]
[Exit Hamlet]

ใน SPL ตัวแยกวิเคราะห์ในตัวซึ่งถูกดาวน์โหลดด้วยโปรแกรมจะปฏิบัติตามกฎที่เฉพาะเจาะจงมากว่าจะเกิดอะไรขึ้นในสคริปต์ หนึ่งในกฎดังกล่าวคือมีเพียงสองตัวละครเท่านั้นที่สามารถอยู่บนเวทีในครั้งเดียว การทำให้ตัวละครออกไปจากเวทีที่ไม่เคยอยู่บนเวทีจะทำให้สับสน เช่นเดียวกับการเพิ่มตัวละครในเวทีที่อยู่บนเวทีแล้ว เมื่อ parser ได้รับข้อผิดพลาดมันจะปฏิเสธที่จะทำสิ่งอื่นใด คุณต้องปิดโปรแกรมและตัวแยกวิเคราะห์อย่างสมบูรณ์จากนั้นเริ่มต้นทุกอย่างอีกครั้ง

ป.ล. ถ้าคุณไม่รู้ว่าภาษานี้ใช้งานได้ดีแค่ไหน Google มันเจ๋งมาก.


1
ดังนั้นมันเป็นข้อผิดพลาดในการแยกวิเคราะห์หรือข้อผิดพลาด runtime?
Fabian Schmengler

4
@fschmengler นั่นเป็นสิ่งเดียวกันสำหรับการตีความภาษา
nwp

13
หากฉันเพิ่มรหัสหลังบรรทัดสุดท้ายมันจะทำงานจริงหรือไม่
Sp3000

@ Sp3000 มันจะพยายามอย่างแน่นอน ...... มันจะปรากฏขึ้นราวกับว่าไม่มีอะไรผิดปกติเกิดขึ้น ... จนกระทั่ง parser ล่ม :)
3.14ed_Piper

43

หูฟัง

ฉันไม่แน่ใจว่าสิ่งนี้มีคุณสมบัติ:

Smalltalk := Nil.

สิ่งนี้จะลบสภาพแวดล้อมแบบรันไทม์ทั้งหมดแขวนเอ็นจิ้นออบเจ็กต์ วิธีเดียวที่จะแก้ไขปัญหานี้ได้คือบังคับให้ยุติกระบวนการและเริ่มต้นใหม่จากการสำรองข้อมูล

สำหรับคนที่ไม่รู้วิธีการทำงานของ Visual Visual Smalltalk นั้นแปลกเล็กน้อย มันเหมือนกับ mini-OS เมื่อคุณเริ่ม Smalltalk คุณจะโหลด "ภาพหน่วยความจำ" ลงใน RAM และมันจะดำเนินการต่อจากจุดที่ค้างไว้ Smalltalk IDE ทั้งหมดเขียนด้วย Smalltalk และสามารถแก้ไขได้แบบไดนามิก

โดยเฉพาะอย่างยิ่งSmalltalkเป็นพจนานุกรมที่มีตัวแปรทั่วโลกทั้งหมด โดยเฉพาะอย่างยิ่งทุกครั้งที่คุณประกาศคลาสใหม่จะมีการสร้างตัวแปรส่วนกลางที่มีชื่อนั้นโดยชี้ไปที่Classวัตถุสำหรับคลาสใหม่ของคุณ ดังนั้นการตั้งค่าSmalltalkเป็นNil(โดยทั่วไปเป็นโมฆะ) จะลบคลาสทั้งหมดในระบบทั้งหมด แม้แต่ตัวจัดการเหตุการณ์ GUI ก็ยังเข้ากันได้

ฉันไม่รู้ว่าทำไมตัวแปรนี้ถึงเขียนได้ อาจเป็นเพราะมันเป็นตัวแปรทั่วโลกและดังนั้นจึงมีอยู่เป็นรายการภายในตัวเอง (หัวของคุณเจ็บหรือยังฉันไม่ได้พูดถึงว่าทุกวัตถุมีชั้นเรียนและชั้นเรียนเป็นวัตถุดังนั้นทุกชั้นมีชั้นเรียนหรือไม่ชั้นของชั้นที่เรียกว่า metaclass แต่ metaclass ยังเป็นวัตถุซึ่งมี ห้องเรียน...)

คุณอาจได้ผลที่คล้ายกันโดยการล้างพจนานุกรมมากกว่าการแทนที่ด้วย null แน่นอนมีหลายสิ่งที่คุณสามารถโค้ดเพื่อลบคลาสทั้งหมดในระบบทำให้คุณไม่สามารถทำอะไรได้ แต่เนื่องจากคอมไพเลอร์ Smalltalk ที่เกิดขึ้นจริงนั้นก็เป็นคลาส ... อะไรก็ตามที่ทำลายภาษาและยังทำลาย IDE ทั้งหมดดังนั้น


มันไม่ถูกต้องถ้ามันแฮงค์ตัวเอง แต่ไม่ใช่คำสั่งถัดไป แต่ฉันอยากรู้อยากเห็น: มีคลาสที่สามารถมีทั้งค่าเป็นคลาสและเป็นวัตถุธรรมดาได้หรือไม่ และคลาสที่มีทั้งค่าเหล่านั้นและคลาสใหม่นี้หรือไม่? และชั้นเรียนของตัวเอง?
jimmy23013

คลาส Smalltalk มีความคล้ายคลึงกับต้นแบบ JavaScript โดยการแฮ็กระบบคลาสอย่างหนักพอคุณสามารถเปลี่ยน Smalltalk เป็นภาษาที่สืบทอดหลายภาษาได้ นอกจากนี้การเรียกใช้เมธอดเป็นวัตถุการบล็อกรหัสเป็นวัตถุ ... คุณสามารถดักจับการเรียกใช้เมธอดที่ไม่ได้กำหนดและทำให้พวกเขาทำสิ่งต่าง ๆ ... มันเป็นภาษาแบบไดนามิกมาก ทุกอย่างเป็นวัตถุ! รวมถึง IDE ...
ทางคณิตศาสตร์

1
ต้องใช้nilแทนNilPharo
mgarciaisaia

5
อีกอันหนึ่งคือtrue become: falseแต่ฉันคิดว่านี่จะไม่ทำงานในภาษาเวอร์ชันใหม่กว่า คุณสามารถฆ่า SmallTalk / V 286 ด้วยวิธีนี้

15
“ ฉันพูดถึงว่าวัตถุทุกอย่างมีคลาสและคลาสเป็นวัตถุดังนั้นทุกคลาสจึงมีคลาสหรือไม่ คลาสของคลาสเรียกว่า metaclass แต่ metaclass ก็เป็นวัตถุด้วยดังนั้นจึงมีคลาส ... ” ในฐานะ Pythonista หัวของฉันไม่ได้เจ็บเลย ในทางตรงกันข้ามฉันคิดว่าฉันรู้สึกเหมือนอยู่บ้านกับ Smalltalk
แบล็กไลท์ส่องแสง

40

Haskell

มีความเป็นไปได้สองสามอย่างที่นี่

ความคิดที่น่าเบื่อ # 1: กำหนดที่mainจะไม่ทำอะไรเลย ตอนนี้ไม่ว่าคุณจะเขียนโค้ดอื่นใดมันก็ไม่สามารถรันได้ (ยกเว้นว่าคุณเรียกใช้ด้วยตนเองจาก REPL)

แนวคิดที่น่าเบื่อ # 2: กำหนดโมดูลโดยไม่มีการส่งออกสาธารณะ ตอนนี้ไม่ว่าคุณจะเขียนโค้ดอื่นใดมันก็ไม่สามารถรันได้

แนวคิดที่น่าสนใจ: ปิดใช้งานการนำเข้าทั้งหมด

module Fubar where
import Prelude ()
foo = foo
-- More code here.

ตอนนี้คุณสามารถกำหนดฟังก์ชั่นซึ่งเป็นที่มองเห็นและสามารถทำงานได้ ... แต่พวกเขาไม่สามารถทำอะไร ขณะนี้ประเภทและฟังก์ชั่นมาตรฐาน Haskell ทั้งหมดถูกซ่อนอยู่ (ยกเว้นบางสิ่งบางอย่างจริงๆ ยากสายเข้าภาษา)

โดยเฉพาะอย่างยิ่งคุณไม่สามารถทำ I / O ใด ๆ ได้ คุณไม่สามารถใช้เลขคณิตความแม่นยำของเครื่องจักรได้ (ตั้งแต่Int, Doubleเป็นต้นไม่ได้ถูกกำหนดเป็นต้น)

คุณยังสามารถเขียนฟังก์ชัน lambda-แคลคูลัสซึ่งทำการคำนวณจริงบางอย่าง คุณไม่สามารถรับข้อมูลเข้าหรือออกจากสิ่งต่างๆได้ แต่แน่นอนคุณสามารถเขียนโมดูลอื่นแยกโมดูลที่เรียกใช้Fubarโมดูลข้างต้นและทำ I / O ในนามของมัน (ซึ่งเป็นการพิสูจน์ว่าโค้ดทำงานและทำสิ่งต่าง ๆ )

รายละเอียดปลีกย่อยบางส่วน:

  • ต้องการการfoo = fooแจ้งแบบจำลองเพื่อป้องกันใครก็ตามที่เพิ่มการนำเข้าเพิ่มเติม (การนำเข้าไม่สามารถปรากฏหลังจากการประกาศ)

  • มีส่วนขยายภาษา Haskell ที่ไม่ได้มาตรฐานมากมายที่จะช่วยให้คุณสามารถปีนออกจากสถานการณ์นี้ได้ แต่ส่วนขยายภาษาจะต้องเปิดใช้งานด้วยคอมไพเลอร์ pragma ที่ด้านบนของไฟล์ (หรือด้วยสวิตช์บรรทัดคำสั่งไปยังคอมไพเลอร์ฉันไม่สามารถป้องกันมันได้!)


-0.1 การใช้foobarงานการสะกดที่คุณใช้มีความหมายที่ไม่ได้ตั้งใจ ...
wizzwizz4

@ wizzwizz4 ฉันค่อนข้างแน่ใจว่า "foobar" เป็นเพียง "fubar" prettied ขึ้นเพื่อหลีกเลี่ยงการเซ็นเซอร์ นั่นเป็นเหตุผลที่ฉันมักจะหลีกเลี่ยงในตัวอย่างการเขียนโปรแกรม
jpmc26

3
@ jpmc26 จริง ๆ แล้วมันมีประวัติอันยาวนานและโดดเด่นผ่านกลุ่มรถไฟจำลองของ MIT ซึ่งได้รับความนิยมในหนังสือเขียนโปรแกรมก่อนที่จะรวมเข้ากับเอกสารประกอบแล้วถูกนำเข้าสู่วัฒนธรรมสมัยนิยม ฉันค่อนข้างแน่ใจว่ามันเป็นเรื่องบังเอิญ
wizzwizz4

ทั้ง "แนวคิดที่น่าเบื่อ" ไม่ถูกต้องเนื่องจากรหัสผู้ใช้ไม่ได้ถูกดำเนินการจริง ( "การคิดที่น่าสนใจ" ดูเหมือนว่าจะถูกต้องแม้ว่า)
pppery

40

PostScript

ใช่ PostScript เป็นภาษาการเขียนโปรแกรม นอกจากนี้ยังเป็นภาษาการเขียนโปรแกรมที่ทุกภาษาสร้างเป็นฟังก์ชั่นที่ระบบกำหนดซึ่งสามารถกำหนดใหม่ ...

1000 dict /Magic def
systemdict {pop Magic exch {} put} forall
Magic begin

เป็นภาษาอังกฤษ:

  • สร้างที่ว่างเปล่าพจนานุกรม 1,000 Magicองค์ประกอบและชื่อ
  • สำหรับทุกคีย์ในsystemdictให้เพิ่มคีย์เดียวกันMagicกับโดยใช้คำจำกัดความที่ว่างเปล่า (" {}")
  • กดMagicลงไปด้านบนสุดของพจนานุกรมสแต็ก

นับจากนี้เป็นต้นไปคำสั่งภาษา PostScript ทุกคำสั่งจะไม่ทำอะไรเลย AFAIK มันเป็นไปไม่ได้ที่จะหนีจากเงื่อนไขนี้

(โดยทางเทคนิคแล้วคุณไม่ได้ "ทำลาย" คำจำกัดความเก่า ๆ คุณแค่ทำมันให้กับเงาถ้าคุณยังสามารถเรียกใช้endงานได้มันจะโผล่Magicออกมาในพจนานุกรมสแต็คยกเลิกคำสั่งทั้งหมดและทำให้คุณมีชีวิต แต่เนื่องจากendตัวมันเองก็เป็นเงา ... มันจะไม่ทำอะไรเลยในตอนนี้)

โปรดทราบว่าคำสั่งทั้งหมดจะยังคงทำงาน ... เพียงตอนนี้พวกเขาถูกกำหนดให้ไม่ทำอะไรเลย คุณจะไม่ได้รับข้อผิดพลาดใด ๆ มันเป็นเพียงแค่ว่าจะไม่มีอะไรเกิดขึ้น (ฉันว่าสแต็คล้นจะเกิดขึ้นในที่สุด ... )


นี่มันตลกจริง ๆ แล้ว ... และก็น่ากลัว ...
Gryphon

34

โปรแกรมใด ๆ ที่ทำงานภายใต้ Linux / x86 (-64)

โปรแกรมนี้เขียนด้วยภาษา C แต่สามารถขัดขวางการทำงานของโปรแกรมใด ๆ ที่ทำงานภายใต้ Linux / x86 (-32 หรือ -64) คุณต่อท้ายการเรียกใช้บรรทัดคำสั่งของโปรแกรมที่คุณต้องการทำลาย

มันใช้ดีบักเกอร์ API เพื่อป้องกันไม่ให้โปรแกรมเป้าหมายสร้างผลลัพธ์ใด ๆ โดยเฉพาะการเรียกระบบทั้งหมดที่สามารถสื่อสารบางสิ่งกับโลกภายนอกกระบวนการ (แน่นอนที่สุดwriteแน่นอน แต่openเมื่อสร้างไฟล์ส่วนใหญ่ของซ็อกเก็ต API killเมื่อนำไปใช้กับกระบวนการอื่น ... ) จะล้มเหลว ราวกับว่าพวกเขาไม่ได้ใช้งาน _exitได้รับอนุญาต แต่รหัสทางออกถูกเขียนทับด้วยศูนย์

ต่างจากรุ่นก่อนหน้าของคำตอบนี้หลาย ๆ โปรแกรมสามารถทำงานเกือบจะเสร็จสมบูรณ์ภายใต้เงื่อนไขเหล่านี้ เป็นเพียงว่างานทั้งหมดของพวกเขาสูญเปล่า ตัวอย่างเช่นถ้าคุณทำ./no-syscalls /bin/ls(สมมติว่า GNU coreutils ls) อ่านไดเรกทอรีทั้งหมดและจัดรูปแบบแล้วการwriteเรียกทั้งหมดเพื่อสร้างผลลัพธ์ที่ล้มเหลว (สิ่งใดก็ตามที่จำเป็นต้องเปิดช่องทางการสื่อสารแบบสองทิศทางเช่นลูกค้า X11 ทั้งหมดจะล้มเหลว ณ จุดนั้นฉันคิดว่าจะอนุญาตsocketแต่ไม่ใช่sendแต่ดูเหมือนว่าจะเปิดช่องโหว่เกินไป)

มีหลายตัวเลือกบรรทัดคำสั่งเพื่อปรับแต่งพฤติกรรม;

-a  log allowed system calls
-d  log denied system calls
-e  deny everything, not just output
-S  permit writes to stderr

โปรแกรมที่ลิงก์แบบไดนามิกจะไม่ออกจากตัวเชื่อมโยงแบบไดนามิกใน-eโหมด -Sเห็นได้ชัดว่าเปิดช่องโหว่ขนาดใหญ่ในนโยบาย แต่สามารถเพลิดเพลินไปกับการชมรายการต่าง ๆ

$ ./no-syscalls -daeS /bin/ls
syscall 59...
syscall 59 = 0
syscall 12 (denied) = -38
syscall 21 (denied) = -38
syscall 9 (denied) = -38
syscall 20...
/bin/ls: error while loading shared libraries: cannot create cache for search path: Cannot allocate memory
syscall 20 = 107
syscall 231...
Program exited, status = 0

คุณต้องอ่านบันทึกผลลัพธ์โดย/usr/include/asm*/unistd.hเปิดในหน้าต่างอื่นเนื่องจากมันค่อนข้างยาวพอสมควรแล้ว

น่าเสียดายที่อินเทอร์เฟซการดีบักเกอร์ที่ใช้นี้มีความสอดคล้องกันอย่างอ่อนระหว่างการใช้งาน Unix เท่านั้นและมีเฉพาะ CPU ภายในเท่านั้น มันจะค่อนข้างตรงไปตรงมาที่จะส่งไปยังซีพียูสถาปัตยกรรมอื่น ๆ (เพียงเพิ่มคำจำกัดความที่เหมาะสมSYSCALL_*_REG) และอาจเป็นไปได้ที่จะย้ายมันไปยังระบบปฏิบัติการยูนิกซ์ใด ๆ ที่มีptraceแต่คุณอาจต้องโคลนกับบัญชีขาว syscall อย่างกว้างขวาง ในptrace.

#define _GNU_SOURCE 1
#include <stddef.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#if defined __linux__
# define SYS_unimplemented -1L
# if defined __i386__
#  define SYSCALL_NUMBER_REG regs.orig_eax
#  define SYSCALL_ARG1_REG   regs.ebx
#  define SYSCALL_ARG2_REG   regs.ecx
#  define SYSCALL_ARG3_REG   regs.edx
#  define SYSCALL_ARG4_REG   regs.esi
#  define SYSCALL_RESULT_REG regs.eax
# elif defined __x86_64__
#  define SYSCALL_NUMBER_REG regs.orig_rax
#  define SYSCALL_ARG1_REG   regs.rdi
#  define SYSCALL_ARG2_REG   regs.rsi
#  define SYSCALL_ARG3_REG   regs.rdx
#  define SYSCALL_ARG4_REG   regs.r10
#  define SYSCALL_RESULT_REG regs.rax
# else
#  error "Need to know system call convention for this CPU"
# endif
#else
# error "Need to know system call convention for this OS"
#endif

static long
xptrace(int request, pid_t pid, void *addr, void *data)
{
  errno = 0;
  long rv = ptrace(request, pid, addr, data);
  if (rv == -1 && errno) {
    perror("ptrace");
    if (pid != 0) kill(pid, SIGKILL);
    exit(1);
  }
  return rv;
}
#define GET_REG_(pid, x) \
  xptrace(PTRACE_PEEKUSER, pid, (void*)offsetof(struct user, x), 0)
#define GET_REG(pid, x) GET_REG_(pid, SYSCALL_##x##_REG)
#define SET_REG_(pid, x, v) \
  xptrace(PTRACE_POKEUSER, pid, (void*)offsetof(struct user, x), (void*)v)
#define SET_REG(pid, x, v) SET_REG_(pid, SYSCALL_##x##_REG, v)

/* This function defines the system-call policy.  */
static int
deny_syscall(pid_t pid, int scnum, int deny_all, int allow_stderr)
{
  switch (scnum) {
  /* These syscalls are unconditionally allowed (when not in -e mode);
     they perform input, or change only process-local state. */
#ifdef SYS_access
  case SYS_access:
#endif
#ifdef SYS_alarm
  case SYS_alarm:
#endif
#ifdef SYS_arch_prctl
  case SYS_arch_prctl:
#endif
#ifdef SYS_brk
  case SYS_brk:
#endif
#ifdef SYS_capget
  case SYS_capget:
#endif
#ifdef SYS_clock_getres
  case SYS_clock_getres:
#endif
#ifdef SYS_clock_gettime
  case SYS_clock_gettime:
#endif
#ifdef SYS_clock_nanosleep
  case SYS_clock_nanosleep:
#endif
#ifdef SYS_close
  case SYS_close:
#endif
#ifdef SYS_dup
  case SYS_dup:
#endif
#ifdef SYS_dup2
  case SYS_dup2:
#endif
#ifdef SYS_dup3
  case SYS_dup3:
#endif
#ifdef SYS_epoll_create
  case SYS_epoll_create:
#endif
#ifdef SYS_epoll_create1
  case SYS_epoll_create1:
#endif
#ifdef SYS_epoll_ctl
  case SYS_epoll_ctl:
#endif
#ifdef SYS_epoll_ctl_old
  case SYS_epoll_ctl_old:
#endif
#ifdef SYS_epoll_pwait
  case SYS_epoll_pwait:
#endif
#ifdef SYS_epoll_wait
  case SYS_epoll_wait:
#endif
#ifdef SYS_epoll_wait_old
  case SYS_epoll_wait_old:
#endif
#ifdef SYS_eventfd
  case SYS_eventfd:
#endif
#ifdef SYS_eventfd2
  case SYS_eventfd2:
#endif
#ifdef SYS_faccessat
  case SYS_faccessat:
#endif
#ifdef SYS_fadvise64
  case SYS_fadvise64:
#endif
#ifdef SYS_fadvise64_64
  case SYS_fadvise64_64:
#endif
#ifdef SYS_fanotify_init
  case SYS_fanotify_init:
#endif
#ifdef SYS_fanotify_mark
  case SYS_fanotify_mark:
#endif
#ifdef SYS_fgetxattr
  case SYS_fgetxattr:
#endif
#ifdef SYS_flistxattr
  case SYS_flistxattr:
#endif
#ifdef SYS_fstat
  case SYS_fstat:
#endif
#ifdef SYS_fstat64
  case SYS_fstat64:
#endif
#ifdef SYS_fstatat64
  case SYS_fstatat64:
#endif
#ifdef SYS_fstatfs
  case SYS_fstatfs:
#endif
#ifdef SYS_fstatfs64
  case SYS_fstatfs64:
#endif
#ifdef SYS_ftime
  case SYS_ftime:
#endif
#ifdef SYS_futex
  case SYS_futex:
#endif
#ifdef SYS_getcpu
  case SYS_getcpu:
#endif
#ifdef SYS_getcwd
  case SYS_getcwd:
#endif
#ifdef SYS_getdents
  case SYS_getdents:
#endif
#ifdef SYS_getdents64
  case SYS_getdents64:
#endif
#ifdef SYS_getegid
  case SYS_getegid:
#endif
#ifdef SYS_getegid32
  case SYS_getegid32:
#endif
#ifdef SYS_geteuid
  case SYS_geteuid:
#endif
#ifdef SYS_geteuid32
  case SYS_geteuid32:
#endif
#ifdef SYS_getgid
  case SYS_getgid:
#endif
#ifdef SYS_getgid32
  case SYS_getgid32:
#endif
#ifdef SYS_getgroups
  case SYS_getgroups:
#endif
#ifdef SYS_getgroups32
  case SYS_getgroups32:
#endif
#ifdef SYS_getitimer
  case SYS_getitimer:
#endif
#ifdef SYS_get_kernel_syms
  case SYS_get_kernel_syms:
#endif
#ifdef SYS_get_mempolicy
  case SYS_get_mempolicy:
#endif
#ifdef SYS_getpeername
  case SYS_getpeername:
#endif
#ifdef SYS_getpgid
  case SYS_getpgid:
#endif
#ifdef SYS_getpgrp
  case SYS_getpgrp:
#endif
#ifdef SYS_getpid
  case SYS_getpid:
#endif
#ifdef SYS_getpmsg
  case SYS_getpmsg:
#endif
#ifdef SYS_getppid
  case SYS_getppid:
#endif
#ifdef SYS_getpriority
  case SYS_getpriority:
#endif
#ifdef SYS_getrandom
  case SYS_getrandom:
#endif
#ifdef SYS_getresgid
  case SYS_getresgid:
#endif
#ifdef SYS_getresgid32
  case SYS_getresgid32:
#endif
#ifdef SYS_getresuid
  case SYS_getresuid:
#endif
#ifdef SYS_getresuid32
  case SYS_getresuid32:
#endif
#ifdef SYS_getrlimit
  case SYS_getrlimit:
#endif
#ifdef SYS_get_robust_list
  case SYS_get_robust_list:
#endif
#ifdef SYS_getrusage
  case SYS_getrusage:
#endif
#ifdef SYS_getsid
  case SYS_getsid:
#endif
#ifdef SYS_getsockname
  case SYS_getsockname:
#endif
#ifdef SYS_getsockopt
  case SYS_getsockopt:
#endif
#ifdef SYS_get_thread_area
  case SYS_get_thread_area:
#endif
#ifdef SYS_gettid
  case SYS_gettid:
#endif
#ifdef SYS_gettimeofday
  case SYS_gettimeofday:
#endif
#ifdef SYS_getuid
  case SYS_getuid:
#endif
#ifdef SYS_getuid32
  case SYS_getuid32:
#endif
#ifdef SYS_getxattr
  case SYS_getxattr:
#endif
#ifdef SYS_inotify_add_watch
  case SYS_inotify_add_watch:
#endif
#ifdef SYS_inotify_init
  case SYS_inotify_init:
#endif
#ifdef SYS_inotify_init1
  case SYS_inotify_init1:
#endif
#ifdef SYS_inotify_rm_watch
  case SYS_inotify_rm_watch:
#endif
#ifdef SYS_ioprio_get
  case SYS_ioprio_get:
#endif
#ifdef SYS_kcmp
  case SYS_kcmp:
#endif
#ifdef SYS_lgetxattr
  case SYS_lgetxattr:
#endif
#ifdef SYS_listxattr
  case SYS_listxattr:
#endif
#ifdef SYS_llistxattr
  case SYS_llistxattr:
#endif
#ifdef SYS_lookup_dcookie
  case SYS_lookup_dcookie:
#endif
#ifdef SYS_lseek
  case SYS_lseek:
#endif
#ifdef SYS_lstat
  case SYS_lstat:
#endif
#ifdef SYS_lstat64
  case SYS_lstat64:
#endif
#ifdef SYS_madvise
  case SYS_madvise:
#endif
#ifdef SYS_mbind
  case SYS_mbind:
#endif
#ifdef SYS_mincore
  case SYS_mincore:
#endif
#ifdef SYS_mlock
  case SYS_mlock:
#endif
#ifdef SYS_mlockall
  case SYS_mlockall:
#endif
#ifdef SYS_mprotect
  case SYS_mprotect:
#endif
#ifdef SYS_mremap
  case SYS_mremap:
#endif
#ifdef SYS_munlock
  case SYS_munlock:
#endif
#ifdef SYS_munlockall
  case SYS_munlockall:
#endif
#ifdef SYS_munmap
  case SYS_munmap:
#endif
#ifdef SYS_name_to_handle_at
  case SYS_name_to_handle_at:
#endif
#ifdef SYS_nanosleep
  case SYS_nanosleep:
#endif
#ifdef SYS_newfstatat
  case SYS_newfstatat:
#endif
#ifdef SYS_nice
  case SYS_nice:
#endif
#ifdef SYS_oldfstat
  case SYS_oldfstat:
#endif
#ifdef SYS_oldlstat
  case SYS_oldlstat:
#endif
#ifdef SYS_oldolduname
  case SYS_oldolduname:
#endif
#ifdef SYS_oldstat
  case SYS_oldstat:
#endif
#ifdef SYS_olduname
  case SYS_olduname:
#endif
#ifdef SYS_pause
  case SYS_pause:
#endif
#ifdef SYS_perf_event_open
  case SYS_perf_event_open:
#endif
#ifdef SYS_personality
  case SYS_personality:
#endif
#ifdef SYS_pivot_root
  case SYS_pivot_root:
#endif
#ifdef SYS_poll
  case SYS_poll:
#endif
#ifdef SYS_ppoll
  case SYS_ppoll:
#endif
#ifdef SYS_prctl
  case SYS_prctl:
#endif
#ifdef SYS_pread64
  case SYS_pread64:
#endif
#ifdef SYS_preadv
  case SYS_preadv:
#endif
#ifdef SYS_prlimit64
  case SYS_prlimit64:
#endif
#ifdef SYS_pselect6
  case SYS_pselect6:
#endif
#ifdef SYS_query_module
  case SYS_query_module:
#endif
#ifdef SYS_read
  case SYS_read:
#endif
#ifdef SYS_readahead
  case SYS_readahead:
#endif
#ifdef SYS_readdir
  case SYS_readdir:
#endif
#ifdef SYS_readlink
  case SYS_readlink:
#endif
#ifdef SYS_readlinkat
  case SYS_readlinkat:
#endif
#ifdef SYS_readv
  case SYS_readv:
#endif
#ifdef SYS_recvfrom
  case SYS_recvfrom:
#endif
#ifdef SYS_recvmmsg
  case SYS_recvmmsg:
#endif
#ifdef SYS_recvmsg
  case SYS_recvmsg:
#endif
#ifdef SYS_remap_file_pages
  case SYS_remap_file_pages:
#endif
#ifdef SYS_request_key
  case SYS_request_key:
#endif
#ifdef SYS_restart_syscall
  case SYS_restart_syscall:
#endif
#ifdef SYS_rt_sigaction
  case SYS_rt_sigaction:
#endif
#ifdef SYS_rt_sigpending
  case SYS_rt_sigpending:
#endif
#ifdef SYS_rt_sigprocmask
  case SYS_rt_sigprocmask:
#endif
#ifdef SYS_rt_sigreturn
  case SYS_rt_sigreturn:
#endif
#ifdef SYS_rt_sigsuspend
  case SYS_rt_sigsuspend:
#endif
#ifdef SYS_rt_sigtimedwait
  case SYS_rt_sigtimedwait:
#endif
#ifdef SYS_sched_getaffinity
  case SYS_sched_getaffinity:
#endif
#ifdef SYS_sched_getattr
  case SYS_sched_getattr:
#endif
#ifdef SYS_sched_getparam
  case SYS_sched_getparam:
#endif
#ifdef SYS_sched_get_priority_max
  case SYS_sched_get_priority_max:
#endif
#ifdef SYS_sched_get_priority_min
  case SYS_sched_get_priority_min:
#endif
#ifdef SYS_sched_getscheduler
  case SYS_sched_getscheduler:
#endif
#ifdef SYS_sched_rr_get_interval
  case SYS_sched_rr_get_interval:
#endif
#ifdef SYS_sched_setaffinity
  case SYS_sched_setaffinity:
#endif
#ifdef SYS_sched_setattr
  case SYS_sched_setattr:
#endif
#ifdef SYS_sched_setparam
  case SYS_sched_setparam:
#endif
#ifdef SYS_sched_setscheduler
  case SYS_sched_setscheduler:
#endif
#ifdef SYS_sched_yield
  case SYS_sched_yield:
#endif
#ifdef SYS_select
  case SYS_select:
#endif
#ifdef SYS_setfsgid
  case SYS_setfsgid:
#endif
#ifdef SYS_setfsgid32
  case SYS_setfsgid32:
#endif
#ifdef SYS_setfsuid
  case SYS_setfsuid:
#endif
#ifdef SYS_setfsuid32
  case SYS_setfsuid32:
#endif
#ifdef SYS_setgid
  case SYS_setgid:
#endif
#ifdef SYS_setgid32
  case SYS_setgid32:
#endif
#ifdef SYS_setgroups
  case SYS_setgroups:
#endif
#ifdef SYS_setgroups32
  case SYS_setgroups32:
#endif
#ifdef SYS_setitimer
  case SYS_setitimer:
#endif
#ifdef SYS_setns
  case SYS_setns:
#endif
#ifdef SYS_setpgid
  case SYS_setpgid:
#endif
#ifdef SYS_setpriority
  case SYS_setpriority:
#endif
#ifdef SYS_setregid
  case SYS_setregid:
#endif
#ifdef SYS_setregid32
  case SYS_setregid32:
#endif
#ifdef SYS_setresgid
  case SYS_setresgid:
#endif
#ifdef SYS_setresgid32
  case SYS_setresgid32:
#endif
#ifdef SYS_setresuid
  case SYS_setresuid:
#endif
#ifdef SYS_setresuid32
  case SYS_setresuid32:
#endif
#ifdef SYS_setreuid
  case SYS_setreuid:
#endif
#ifdef SYS_setreuid32
  case SYS_setreuid32:
#endif
#ifdef SYS_setrlimit
  case SYS_setrlimit:
#endif
#ifdef SYS_set_robust_list
  case SYS_set_robust_list:
#endif
#ifdef SYS_setsid
  case SYS_setsid:
#endif
#ifdef SYS_set_thread_area
  case SYS_set_thread_area:
#endif
#ifdef SYS_set_tid_address
  case SYS_set_tid_address:
#endif
#ifdef SYS_setuid
  case SYS_setuid:
#endif
#ifdef SYS_setuid32
  case SYS_setuid32:
#endif
#ifdef SYS_sigaction
  case SYS_sigaction:
#endif
#ifdef SYS_sigaltstack
  case SYS_sigaltstack:
#endif
#ifdef SYS_signal
  case SYS_signal:
#endif
#ifdef SYS_signalfd
  case SYS_signalfd:
#endif
#ifdef SYS_signalfd4
  case SYS_signalfd4:
#endif
#ifdef SYS_sigpending
  case SYS_sigpending:
#endif
#ifdef SYS_sigprocmask
  case SYS_sigprocmask:
#endif
#ifdef SYS_sigreturn
  case SYS_sigreturn:
#endif
#ifdef SYS_sigsuspend
  case SYS_sigsuspend:
#endif
#ifdef SYS_socketpair
  case SYS_socketpair:
#endif
#ifdef SYS_stat
  case SYS_stat:
#endif
#ifdef SYS_stat64
  case SYS_stat64:
#endif
#ifdef SYS_statfs
  case SYS_statfs:
#endif
#ifdef SYS_statfs64
  case SYS_statfs64:
#endif
#ifdef SYS_sysfs
  case SYS_sysfs:
#endif
#ifdef SYS_sysinfo
  case SYS_sysinfo:
#endif
#ifdef SYS_time
  case SYS_time:
#endif
#ifdef SYS_timer_create
  case SYS_timer_create:
#endif
#ifdef SYS_timer_delete
  case SYS_timer_delete:
#endif
#ifdef SYS_timerfd_create
  case SYS_timerfd_create:
#endif
#ifdef SYS_timerfd_gettime
  case SYS_timerfd_gettime:
#endif
#ifdef SYS_timerfd_settime
  case SYS_timerfd_settime:
#endif
#ifdef SYS_timer_getoverrun
  case SYS_timer_getoverrun:
#endif
#ifdef SYS_timer_gettime
  case SYS_timer_gettime:
#endif
#ifdef SYS_timer_settime
  case SYS_timer_settime:
#endif
#ifdef SYS_times
  case SYS_times:
#endif
#ifdef SYS_ugetrlimit
  case SYS_ugetrlimit:
#endif
#ifdef SYS_ulimit
  case SYS_ulimit:
#endif
#ifdef SYS_umask
  case SYS_umask:
#endif
#ifdef SYS_uname
  case SYS_uname:
#endif
#ifdef SYS_unshare
  case SYS_unshare:
#endif
#ifdef SYS_uselib
  case SYS_uselib:
#endif
#ifdef SYS_ustat
  case SYS_ustat:
#endif
#ifdef SYS_wait4
  case SYS_wait4:
#endif
#ifdef SYS_waitid
  case SYS_waitid:
#endif
#ifdef SYS_waitpid
  case SYS_waitpid:
#endif
    return deny_all;

#ifdef SYS_exit
  case SYS_exit:
#endif
#ifdef SYS_exit_group
  case SYS_exit_group:
#endif
    /* Special case: exiting is allowed, even in -e mode,
       but the exit status is forced to 0. */
    SET_REG(pid, ARG1, 0);
    return 0;

#ifdef SYS_fcntl
  case SYS_fcntl:
#endif
#ifdef SYS_fcntl64
  case SYS_fcntl64:
#endif
    /* Special case: fcntl is allowed, but only for the *FD and *FL
       operations.  This is a compromise between not allowing it at
       all, which would break some interpreters, and trying to go
       through the dozens of extended ops and figure out which ones
       can affect global state.  */
    {
      int cmd = GET_REG(pid, ARG2);
      if (cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC ||
          cmd == F_GETFD || cmd == F_SETFD || cmd == F_SETFL || cmd == F_GETFL)
        return deny_all;
    }
    return 1;

#ifdef SYS_kill
  case SYS_kill:
#endif
#ifdef SYS_rt_sigqueueinfo
  case SYS_rt_sigqueueinfo:
#endif
#ifdef SYS_rt_tgsigqueueinfo
  case SYS_rt_tgsigqueueinfo:
#endif
#ifdef SYS_tkill
  case SYS_tkill:
#endif
#ifdef SYS_tgkill
  case SYS_tgkill:
#endif
    /* Special case: kill is allowed if and only if directed to the calling
       process. */
    {
      pid_t kpid = GET_REG(pid, ARG1);
      if (kpid == pid)
        return deny_all;
    }
    return 1;

#ifdef SYS_mmap
  case SYS_mmap:
#endif
#ifdef SYS_mmap2
  case SYS_mmap2:
#endif
    /* Special case: mmap is allowed if it is private or read-only.  */
    {
      int prot  = GET_REG(pid, ARG3);
      int flags = GET_REG(pid, ARG4);
      if ((flags & (MAP_SHARED|MAP_PRIVATE)) == MAP_PRIVATE)
        return deny_all;
      if (!(prot & PROT_WRITE))
        return deny_all;
    }
    return 1;

    /* Special case: open() variants are allowed only if read-only and
       not creating. */
#ifdef SYS_open
  case SYS_open:
#endif
#ifdef SYS_openat
  case SYS_openat:
#endif
#ifdef SYS_open_by_handle_at
  case SYS_open_by_handle_at:
#endif
    {
      int flags = ((scnum == SYS_open)
                   ? GET_REG(pid, ARG2)
                   : GET_REG(pid, ARG3));
      if (!(flags & O_CREAT) && ((flags & O_ACCMODE) == O_RDONLY))
        return deny_all;
    }
    return 1;

#ifdef SYS_write
  case SYS_write:
#endif
#ifdef SYS_write64
  case SYS_write64:
#endif
#ifdef SYS_writev
  case SYS_writev:
#endif
#ifdef SYS_pwrite
  case SYS_pwrite:
#endif
#ifdef SYS_pwrite64
  case SYS_pwrite64:
#endif
#ifdef SYS_pwritev
  case SYS_pwritev:
#endif
    /* Special case: optionally, the program is allowed to write to
       stderr.  This opens a gaping hole in the policy, but it can be
       quite entertaining to watch programs moan about how nothing works. */
    if (allow_stderr) {
      int fd = GET_REG(pid, ARG1);
      if (fd == 2)
        return 0;
    }
    return 1;

  default:
    /* All other system calls are unconditionally denied. */
    return 1;
  }
}

static void
usage(char *progname)
{
  fprintf(stderr, "usage: %s [-adeS] program args...\n", progname);
  fputs("\t-a  log allowed system calls\n"
        "\t-d  log denied system calls\n"
        "\t-e  deny everything, not just output\n"
        "\t-S  permit writes to stderr\n", stderr);
  exit(2);
}

int
main(int argc, char **argv)
{
  pid_t pid;
  int   status;
  int   opt;
  long  last_syscall = SYS_unimplemented;
  int   last_allowed = 0;
  int   after_execve = 0;
  int   trace_active = 0;
  int   allow_stderr = 0;
  int   deny_all     = 0;
  int   log_allowed  = 0;
  int   log_denied   = 0;

  while ((opt = getopt(argc, argv, "+adeS")) != -1) {
    switch (opt) {
    case 'a': log_allowed  = 1; break;
    case 'd': log_denied   = 1; break;
    case 'e': deny_all     = 1; break;
    case 'S': allow_stderr = 1; break;
    default:
      usage(argv[0]);
    }
  }
  if (optind == argc) {
    usage(argv[0]);
  }

  setvbuf(stdout, 0, _IOLBF, 0);
  setvbuf(stderr, 0, _IOLBF, 0);

  pid = fork();
  if (pid == -1) {
    perror("fork");
    exit(1);

  } else if (pid == 0) {
    raise(SIGSTOP); /* synch with parent */
    execvp(argv[optind], argv+optind);
    perror("execvp");
    exit(1);
  }

  /* If we get here, we are the parent. */
  for (;;) {
    pid_t rv = waitpid(pid, &status, WUNTRACED);
    if (rv != pid) {
      perror("waitpid");
      kill(pid, SIGKILL);
      exit(1);
    }
    if (!WIFSTOPPED(status)) {
      if (WIFEXITED(status))
        printf("Program exited, status = %d\n", WEXITSTATUS(status));
      else if (WIFSIGNALED(status))
        printf("Program killed by signal %d\n", WTERMSIG(status));
      else {
        printf("Un-decodable status %04x\n", status);
        kill(pid, SIGKILL); /* just in case */
      }
      exit(0);
    }
    if (WSTOPSIG(status) == SIGSTOP && !trace_active) {
      /* This is the raise(SIGSTOP) on the child side of the fork. */
      trace_active = 1;
      xptrace(PTRACE_SEIZE, pid, 0, (void*)PTRACE_O_TRACESYSGOOD);
      xptrace(PTRACE_SYSCALL, pid, 0, 0);
    }
    else if (WSTOPSIG(status) == (SIGTRAP|0x80)) {
      if (last_syscall == SYS_unimplemented) {
        last_syscall = GET_REG(pid, NUMBER);
        /* The child process is allowed to execute normally until an
           execve() succeeds.  */
        if (after_execve && deny_syscall(pid, last_syscall,
                                         deny_all, allow_stderr)) {
          last_allowed = 0;
          SET_REG(pid, NUMBER, SYS_unimplemented);
        } else {
          last_allowed = 1;
          if (log_allowed) {
            /* Log this now, we may not get another chance. */
            printf("syscall %ld...\n", last_syscall);
          }
        }
      } else {
        if (last_allowed ? log_allowed : log_denied) {
          long scret = GET_REG(pid, RESULT);
          printf("syscall %ld%s = %ld\n",
                 last_syscall, last_allowed ? "" : " (denied)", scret);
        }
        if (last_allowed && (last_syscall == SYS_execve ||
                             last_syscall == SYS_execveat)) {
          long scret = GET_REG(pid, RESULT);
          if (scret == 0)
            after_execve = 1;
        }
        last_syscall = SYS_unimplemented;
      }
      xptrace(PTRACE_SYSCALL, pid, 0, 0);
    }
    else if (WSTOPSIG(status) == SIGTRAP) {
      /* Swallow all SIGTRAPs, they are probably spurious debug events. */
      xptrace(PTRACE_SYSCALL, pid, 0, 0);
    } else {
      /* Allow all normal signals to proceed unmolested. */
      if (log_allowed) {
        printf("process received signal %d\n", WSTOPSIG(status));
      }
      xptrace(PTRACE_SYSCALL, pid, 0, (void*)(uintptr_t)WSTOPSIG(status));
    }
  }
}

1
“ เป้าหมายสามารถอ่านอาร์กิวเมนต์บรรทัดคำสั่งของตนทำการคำนวณแบบบริสุทธิ์และสร้างสถานะการออก 8 บิต แต่จะไม่สามารถจัดสรรหน่วยความจำหรือทำ I / O” - ฉันคิดว่าคุณยังคงมีคุณสมบัติตามเกณฑ์ทั้งสี่ . จำนวนเต็มสามารถตีความได้จากอาร์กิวเมนต์บรรทัดคำสั่ง สถานะการออกสามารถยกระดับสำหรับการส่งออกง่าย นอกจากนี้ยังไม่ได้ขัดขวาง; และสิ่งที่คุณต้องการสำหรับการทดสอบขั้นแรกคือความสามารถในการคำนวณบริสุทธิ์บิตของพื้นที่สแต็กและลูป
แบล็กไลท์ส่องแสง

1
@ BlacklightShining ฉันคิดว่าสิ่งนี้บรรลุข้อ จำกัด ขนาดใหญ่เมื่อเทียบกับพฤติกรรมปกติที่ควรยอมรับแม้ว่าคุณจะยังสามารถเขียนผู้ทดสอบหลักได้ แต่-DNO_EXITโหมดนี้เหมาะสำหรับผู้ที่รู้สึกเหมือนคุณ ไม่สามารถใช้เอาต์พุตที่สื่อความหมายได้ในโหมดนั้น
zwol

1
@ BlacklightShining ฉันคิดเกี่ยวกับมันมากขึ้นและฉันเขียนโปรแกรมใหม่โดยทั่วไปตั้งแต่เริ่มต้น ตอนนี้มันค่อนข้างฉลาดกว่านี้แล้วและฉันหวังว่าจะได้พบกับการอ่านที่ท้าทายที่สุด
zwol

2
@ โจชัวฉลาดและยากที่จะป้องกันการใช้วิธีการนี้ (เนื่องจากโปรแกรมเพิ่งแก้ไขหน่วยความจำของตัวเอง) แต่ในปัจจุบันยังไม่อยู่ในรายการ "วิธีการแสดงผลที่ได้รับอนุญาต"
zwol

6
@JesseTG คุณคุ้นเคยstraceหรือไม่
zwol

30

เท็กซ์

\catcode`\\=10

ฉันไม่แน่ใจว่ามันจะใช้งานได้จริง แต่ในทางทฤษฎีแล้วสิ่งนี้น่าจะ\เป็นตัวละครที่ทำให้คุณไม่สามารถแก้ไขได้ โดยปกติ TeX สามารถอ่านและเขียนไฟล์ได้ตอนนี้มันไม่สามารถเขียนอะไรก็ได้ที่ขึ้นอยู่กับตรรกะ ดังนั้นภาษาจะแตกตามที่กำหนดโดย OP

แก้ไข: คำสั่งฆ่าอื่น ๆ ที่นำมาจากความคิดเห็น (แม้ว่าทั้งสองอาจละเมิดกฎรหัสจะต้องถูกดำเนินการ):

  • \def\fi{}\iffalseโดยsmplจะสร้างการปิดไม่ได้ถ้าสาขา
  • \catcode13=9%โดยiwillnotexist idonotexistสร้างความคิดเห็นที่ไม่มีที่สิ้นสุด

3
รุ่นที่ดีกว่า: \def\fi{}\iffalse. ฉันไม่สามารถโพสต์คำตอบเกี่ยวกับเรื่องนี้เพราะมันต้องมีตัวแทนอย่างน้อย 10 รายที่ได้รับจากเว็บไซต์นี้ แต่จะไม่อนุญาตให้แสดงผลอีกต่อไป
user530873

1
@smpl คุณยังคงสามารถนิยาม\fiความหมายดั้งเดิมได้ใช่ไหม ดังนั้นภาษาไม่แตกหักเกินกว่าจะซ่อมได้
Cephalopod

1
@Cephalopod \fiเป็น TeX ดั้งเดิม และไม่มีใครที่คุณไม่สามารถกำหนดสิ่งใด ณ จุดนี้\iffalseได้ถูกเรียก
user530873

1
@smpl อืมฉันเข้าใจแล้ว ฉลาดมาก.
Cephalopod

1
+1 ฉันเพิ่งเริ่มสอนตัวเองจาก TeXBook และเมื่อฉันรู้ว่า\catcode13=9%จะแตกภาษาอย่างสมบูรณ์ (ทุกอย่างหลังจากที่%ถูกคอมเมนท์และบรรทัดใหม่ (ASCII ถ่าน 13) จะถูกละเว้นดังนั้นความคิดเห็นจึงขยายไปถึงอินฟินิตี้) ฉันต้องการโพสต์ที่นี่ แต่คุณมีคำสั่งอีกต่อไปแล้วเล็กน้อยที่นี่แล้ว
Iwillnotexist Idonotexist

29

เกา

ทำลายภาพเกา
when [timer v] > (0)จะทำงานทันทีที่รหัส initialised ซึ่งถ้าคุณอยู่ในการแก้ไขคือก่อนที่คุณจะเริ่มต้นรหัส when I receive (join[][])จะทำให้เกิดข้อผิดพลาดจะถูกโยนทุกสิ่งที่จะออกอากาศเวลาหยุดโค้ดถ้าคุณมีรุ่นสำหรับนักพัฒนาของ Flash breakฟังก์ชั่นจะสร้างโคลนและเกิดข้อผิดพลาดการออกอากาศ ทุกหนึ่งโคลนจะใช้เวลาสองวินาทีสุดท้ายจากนั้นลบตัวมันเอง และทุก ๆ โคลนจะตอบสนองต่อการwhen [timer v] > (0)เรียกใช้breakรูทีนย่อยและรีเซ็ตตัวจับเวลาซึ่งทำให้โค้ดตัวจับเวลาทำงานอีกครั้ง นอกจากนี้แต่ละโคลนจะตอบสนองต่อข้อผิดพลาดในการออกอากาศทุกครั้งเช่นกันซึ่งหมายถึงจำนวนข้อผิดพลาดต่อการประเมินผลbreakคือจำนวนของโคลนนิ่งกำลังสอง ฉันลืมที่จะพูดถึงbreakฟังก์ชั่นที่มีrun without screen refreshทำเครื่องหมายแล้วทำให้ตัวแก้ไขตรึง jolt และ lag รวมถึงหน่วยความจำโลภและการจัดสรร และ CPU สูงสุด

รหัสใด ๆ ก็ตามที่เพิ่มเข้ามาด้วยการวิ่งนี้จะพบว่าตัวเองไม่สามารถสร้างโคลนได้ (เกินขีด จำกัด การโคลน 300 ครั้ง) รวมถึงการทำให้เครื่องร้อนและหยุดการทำงานของคอมพิวเตอร์ และจับหน่วยความจำจนกว่าจะไม่มีอีกต่อไปที่จะคว้าออกจากตัวแปรที่ทำงานผิดปกติ

และหลังจากที่มีความล่าช้ามากเกินไปที่จะเรียกwhen [timer v] > (0)บล็อกมันจะยังคงทำงานbreakอยู่

ขอบคุณ @towerofnix ที่เตือนฉันเกี่ยวกับความwhen I receiveผิดพลาดที่ฉันพบในขณะที่กลับมาและให้ความคิดแก่run without screen refreshฉัน หากคุณชอบสิ่งนี้นี่คือต้นฉบับ: https://codegolf.stackexchange.com/a/61357/43394


+1 นอกจากนี้ยังอาจสนุกกับการเรียกใช้บล็อกอะตอม (รันโดยไม่ต้องรีเฟรชหน้าจอ) ด้วยstop this script: P
Florrie

" when I receiveความผิดพลาด" ทำงานอย่างไร
Scimonster

@Scimonster when I receiveบล็อกหมวกถูกออกแบบมาเพื่อรับข้อมูลจากรายการแบบเลื่อนลงเท่านั้น join[][]บล็อกส่งกลับชนิดข้อมูลที่when I recieveบล็อกไม่ได้ออกแบบมาเพื่อที่จะยอมรับ ทุกครั้งที่มีการถ่ายทอดสิ่งใดบล็อกหมวกทั้งหมดจะตรวจสอบและประเมินค่าตอบแทนของบล็อกโดยโยนincorrect typeข้อผิดพลาด
wizzwizz4

ฉันเห็น. แม้ว่าคุณจะต้องแฮ็คไฟล์ JSON เพื่อรับjoinบล็อกในนั้น
Scimonster

1
@ppperry มันขึ้นอยู่กับรุ่นของ Flash ที่ไม่สนใจข้อผิดพลาด - มันมีอยู่จริง นำมาซึ่งความสุดขีด "ที่มีขนาดเล็กพอn" อาจถูกนำมาใช้เพื่อบอกว่า(n-1)ผลงานเป็นบวกn<3 แต่เนื่องจากนี่เป็นพื้นฐานของอัลกอริทึมอัลกอริธึมที่ดีควรจะสามารถทำให้nมีขนาดใหญ่พอที่จะยักแย้งได้ ฉันไม่แน่ใจว่าเครื่องที่เร็วขึ้นหรือช้าลงจะทำให้ใช้งานได้มากขึ้นหรือไม่ อย่างไรก็ตามฉันยอมรับว่าโซลูชันนี้สามารถแก้ไขได้ มันไม่ใช่ตำรวจและโจรแต่ทำได้ดีอยู่แล้ว
wizzwizz4

27

ภาษา Mathematica / Wolfram

Mathematica เป็นภาษาที่ตีความซึ่งชื่อคำสั่งเป็นสัญลักษณ์ที่โปรแกรมเมอร์สามารถควบคุมได้ คุณไม่สามารถลบโอเปอเรเตอร์ในตัวได้ แต่คุณสามารถโหลดเกินหรือแก้ไขการทำงานได้ ต่อไปนี้สัญญาณรบกวนคำสั่ง "ด้วย" ซึ่งเป็นสิ่งจำเป็นสำหรับการกำหนดให้กับตัวแปรแม้แต่ภายใน การเปลี่ยนแปลงนี้ป้องกันเคอร์เนลจากการเก็บอาร์กิวเมนต์ที่ไม่ได้ประเมินค่าจนกว่าการกำหนดจะเสร็จสมบูรณ์และจะฆ่าภาษาค่อนข้างตาย

ClearAttributes["With", HoldAll]

หากคำสั่งนี้ถูกเรียกใช้ในเซสชันแบบโต้ตอบหรือภายในบล็อกของรหัส Mathematica จะไม่สามารถเพิ่มได้1+1(ข้อความแสดงข้อผิดพลาดที่เกิดขึ้นนั้นยาวประมาณหน้าหนึ่งดังนั้นฉันจะไม่รวมที่นี่)


26

PHP

ฉันประหลาดใจว่ามันใช้งานได้จริง แต่ปิดSTDOUTและSTDERRระงับการส่งออกทั้งหมด เพื่อให้แน่ใจว่าพวกเขาจะไม่ถูกเปิดอีกครั้งเราเปิด/dev/nullสามครั้งเพื่อกำหนดไฟล์ตัวอธิบาย 0, 1 และ 2 อีกครั้ง:

<?php
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
fopen('/dev/null','r');
fopen('/dev/null','w');
fopen('/dev/null','w');

// insert program here

เพิ่มเติมเกี่ยวกับที่: https://stackoverflow.com/questions/937627/how-to-redirect-stdout-to-a-file-in-php


มีรูปแบบเอาต์พุตที่ถูกต้องอื่น ๆ รวมถึงการเขียนไปยังไฟล์และการใช้รหัสออกของโปรแกรม ดูลิงค์ในสัญลักษณ์แสดงหัวข้อย่อยที่เกี่ยวข้องของข้อมูลจำเพาะ
Martin Ender

1
สิ่งที่ได้รับอนุญาตและไม่ชัดเจนสำหรับฉัน ในแท็ก wiki ตัวอย่างฉันไม่พบอะไรเกี่ยวกับไฟล์และรหัสทางออก แต่ถ้าพวกเขาได้รับอนุญาตฉันไม่คิดว่าฉันจะเปลี่ยนให้เป็นการส่งที่ถูกต้องได้
Fabian Schmengler

แก้ไขคำถามเพื่ออนุญาตให้ปิดใช้งานรูปแบบเอาต์พุตเดียวเท่านั้น
jimmy23013

20
@ jimmy23013 อะไรนะ? นั่นเอาชนะจุดคำถามอย่างสมบูรณ์
ฮอบส์

5
@ jimmy23013 หากมันถูกต้องเพียงแค่ปิดการใช้งานรูปแบบการส่งออกเดียวเท่านั้นตัวอย่างเช่นการระงับรหัสออกของโปรแกรม (ตามที่ Martin แนะนำ) เป็นสิ่งที่ฉันต้องทำถึงแม้ว่าภาษานั้นจะใช้งานได้อย่างสมบูรณ์โดยไม่ต้องใช้รหัสออก?
Jerry Jeremiah

24

ชุด DOS (ก่อนหน้า Windows 95 ฉันเชื่อ)

CTTY

ออกโดยไม่มีอาร์กิวเมนต์จะยกเลิกการเชื่อมต่อบรรทัดคำสั่งจากเทอร์มินัล ความพยายามเพิ่มเติมในการอ่านอินพุตหรือสร้างเอาต์พุตไม่ได้ทำอะไร

ในกรณีที่คุณต้องการทราบวิธีใช้ CTTY อย่างถูกต้อง:

MODE COM1,8600,8,N,1
CTTY COM1

ไฟล์แบตช์ที่ทรงพลังกว่าเล็กน้อยสามารถรับโมเด็มได้และเชื่อมต่อทุกสิ่งที่โทรเข้าสู่ CTTY


23

เสียงกระเพื่อมสามัญ

(set-macro-character #\( (lambda (x y) ()))

ฉันหวังว่าคุณไม่จำเป็นต้องใช้วงเล็บเปิด

นี่คือแมโครตัวอ่านที่บอกให้ Lisp Reader แทนที่แต่ละอินสแตนซ์(ด้วยการเรียก(lambda (x y) ())ใช้ฟังก์ชันที่รับอาร์กิวเมนต์สองตัวและไม่ส่งคืนอะไรเลย ดังนั้นสำหรับตัวอย่างเช่นมันจะอ่าน(foo)เป็นfoo)ตีความเป็นตัวแปรแล้วโยนข้อผิดพลาดที่ไม่ตรงกันในวงเล็บfoo0


2
ได้โปรดตีความ)ว่าเป็นสิ่งที่แตกสลายด้วย! ด้วยวิธีนี้จะมีข้อผิดพลาดน้อยลง
wizzwizz4

7
ฉันรักสิ่งนี้. "เสียงกระเพื่อมอะไรขึ้นอยู่กับตัวละครตัวเดียว? มันน่าละอายถ้ามีอะไรเกิดขึ้นกับมัน ... " มันเป็นตรรกะเดียวกับการนิยามใหม่ `` `ใน TeX
felixphew

23

เกา

นี่เป็นตัวอย่างง่ายๆที่จะทำให้เบราว์เซอร์ของคุณขัดข้อง (และในทางทฤษฎีแล้วคอมพิวเตอร์ของคุณ):

ความผิดพลาดทันที

ฉันออกจากการทำงานนี้ประมาณยี่สิบวินาทีจากนั้นหน่วยความจำ 2.65 GB หายไปเพื่อทำการลบทิ้ง เพียงชั่วครู่ต่อมาและ 5 GB ก็หายไป

ฉันขอแนะนำให้คุณมีวิธีบังคับให้ออกจาก Adobe Flash หรือเว็บเบราว์เซอร์ของคุณก่อนใช้งาน!


ฉันจริงๆอยากจะให้คำตอบที่เย็นเช่นclear(this)JS หนึ่ง แต่รอยขีดข่วนเศร้าไม่ได้มีวิธีการใด ๆ ที่จะทำเช่นนั้น อย่าลังเลที่จะอัพเดทโพสต์นี้ (หรือสร้างของคุณเอง) หากคุณหาวิธีอื่นในการทำให้ Scratch ใช้ไม่ได้!


2
คุณจะเพิ่มรหัสผู้ใช้จากที่ใดและมีการใช้งานจริงหรือไม่
jimmy23013

รหัสผู้ใช้ ทุกที่ในโครงการตราบใดที่มีการแทรกตัวอย่างนี้ มันถูกเรียกใช้งานครั้งเดียว 0.3 วินาทีหลังจากการเรียกใช้ครั้งแรกและจากนั้นทุก 0.3 วินาที (ยกเว้นว่าจะรันสคริปต์อีกครั้งโดยไม่มีจุดสิ้นสุดทำให้เกิดรอยขีดข่วนช้ามาก) ไม่เป็นไรถ้าฉันอัปเดตโพสต์นี้ด้วย crasher ที่ดีขึ้นและมีประสิทธิภาพมากขึ้น?
Florrie

5
ใครบางคนที่ใช้ Scratch ... d: -D YAY !!!
wizzwizz4

@towerofnix โดยวิธีการที่ฉันได้รับการปรับปรุง / แก้ไขอย่างรุนแรง / สร้างขึ้นใหม่ที่นี่: codegolf.stackexchange.com/a/61490/43394 Mine ไม่พึ่งพาไมโครโฟนที่ใช้
wizzwizz4

1
@ wizzwizz4 ใช่คุณดีกว่าของฉันมาก โปรดไปโหวตให้เขา
Florrie

20

Thue

::=

ด้วยการขึ้นบรรทัดใหม่ในตอนท้าย

ภาษาเหล่านี้อาศัยการกำหนดชุดกฎและ::=แสดงถึงจุดสิ้นสุดของชุดกฎ มันเป็นไปไม่ได้เลยที่จะทำสิ่งใดในสิ่งเหล่านี้โดยไม่กำหนดกฎที่ทำดังนั้นไม่ว่าคุณจะทำ::=อะไร

ทางเลือกคำตอบ

A::=
B::=
C::=
D::=
E::=
F::=
G::=
H::=

(และต่อไปสำหรับอักขระทุกตัวใน Unicode ทั้งหมดรวมถึงอักขระที่อยู่ก่อนAอักขระและอักขระที่ไม่สามารถพิมพ์ได้) -rเรื่องนี้ต้องมีตัวเลือกบรรทัดคำสั่ง


ฉันเดาว่าข้อความไม่ได้เป็นไวยากรณ์เดียวกับสิ่งที่ตรงตามเกณฑ์ (เช่นชุดกฎ)
jimmy23013

16

MATLAB

โค้ดต่อไปนี้ทำให้สภาพแวดล้อมไม่สามารถใช้งานได้อย่างสมบูรณ์1 :

builtin = @(varargin)false; clear = @(varargin)false;
%// Insert code after this point

สิ่งนี้จะแทนที่builtinฟังก์ชั่นและclearฟังก์ชั่นด้วยฟังก์ชั่นใหม่ที่ไม่ระบุชื่อซึ่งจะส่งกลับfalseทุกครั้งที่คุณลองเรียกใช้ฟังก์ชันเหล่านี้ builtinฟังก์ชั่นเพื่อให้แน่ใจว่าถ้ามีฟังก์ชั่นที่กำหนดเองใด ๆ ที่คุณเขียนใน MATLAB ที่มีชื่อเดียวกับผู้ที่มีในตัว MATLAB (สิ่งที่ชอบsum, max, minฯลฯ ) คุณสามารถที่จะเรียกร้องเหล่านี้อย่างไม่น่าสงสัยแทนการฟังก์ชั่นมากเกินไป . ในทำนองเดียวกันclearช่วยให้คุณสามารถล้างตัวแปรทั้งหมดที่มีการประกาศในปัจจุบันเพื่อให้คุณสามารถเริ่มต้นใหม่อีกครั้ง โดยการลบความสามารถเหล่านี้คุณจะไม่สามารถใช้ MATLAB ได้จนกว่าคุณจะเริ่มต้นโปรแกรมใหม่

ใน MATLAB R2015a ฉันได้รับข้อความต่อไปนี้ด้วย:

ป้อนคำอธิบายรูปภาพที่นี่

เวิร์กสเปซเป็นตัวแปรที่ประกาศในสภาพแวดล้อมเพื่อให้คุณสามารถใช้งานได้ในภายหลัง นี่เป็นการปิดการใช้งานเวิร์กสเปซอย่างถาวรดังนั้นตัวแปรใด ๆ ที่คุณลองและสร้างจะไม่ถูกบันทึกและดังนั้นจึงไม่มีความคืบหน้าเมื่อเรียกใช้งานบรรทัดโค้ดใน MATLAB

1: เครดิตไปที่ผู้ใช้Dev-iLที่ค้นพบความคิดเดิม


2
ใน R2014b คุณสามารถทำได้feval('clear')เพื่อแก้ไข หรือ: s=str2func('clear'); s().
Stewie Griffin

13

///

/\///

การดำเนินการเฉพาะใน /// /pattern/replacement/ซ้ำสตริงทดแทนเช่นนี้

รหัสนี้จะลบทุก ๆ/วิธีที่คุณไม่สามารถใช้การแทนที่สตริงซ้ำได้ดังนั้นโดยทั่วไปทุกอย่างที่คุณเขียนหลังจากนั้นจะถูกพิมพ์ (ยกเว้น/)

คุณยังสามารถใช้งาน\ได้ แต่นั่นก็ไม่ได้ช่วยอะไรมาก


ฉันสงสัยอยู่เสมอว่าเป็นไปได้ไหมที่จะเขียนรหัส /// ซึ่งรับประกันว่าจะลบทุกอย่างหลังจากนั้นและหยุดโดยไม่พิมพ์อะไรเลย ดูเหมือนจะเป็นไปไม่ได้ แต่ฉันไม่ได้คิดว่ามันจะเป็นไปไม่ได้
แทนเนอร์ Swett

12

Befunge-96

'~h

รหัสของผู้ใช้สามารถติดตามได้ทุกที่หลังจากลำดับนี้ตราบใดที่เหล่านี้เป็นอักขระสามตัวแรกในแหล่งที่มา

'คำสั่ง (โหมดหนึ่งสตริง-shot) ผลักดันให้ค่า ASCII ของ~บนสแต็ค (เช่น 126) และhคำสั่งแล้วกำหนดสิ่งที่เป็นที่รู้จักกันเป็นองค์รวมเดลต้ากับค่าที่ สำหรับผู้ที่ไม่คุ้นเคยกับ Befunge-96 Holistic Deltaเป็นออฟเซ็ตที่ถูกเพิ่มเข้าไปในค่าของทุกคำสั่งไบต์ที่ล่ามพบ

เมื่อเดลต้าถูกตั้งค่าเป็น 126 คำสั่งที่ถูกต้องเท่านั้นที่สามารถสร้างได้คือ~(อินพุตอักขระ) ผ่านทาง null ไบต์ในแหล่งที่มา สิ่งอื่นใดที่ไม่ใช่ null จะแปลเป็นค่าที่มากกว่า 126 และไม่มีค่าใดที่จะเป็นคำสั่ง Befunge ที่ถูกต้อง

ฉันคิดว่ามันปลอดภัยที่จะบอกว่านี่จะทำให้ไม่มีคุณสมบัติที่จะมีคุณสมบัติเป็นภาษาโปรแกรม


11

หุยฮา

macro harmless:
    Context.Parameters.Pipeline.Clear()

แล้วที่อื่นในโครงการ

harmless

มาโครแบบง่ายที่มีชื่อที่ไม่ทำให้เกิดเสียง แต่เป็นเอฟเฟกต์ที่น่าผิดหวังอย่างน่าอัศจรรย์ คอมไพเลอร์ Boo ใช้ขั้นตอนหลายขั้นตอนที่เริ่มต้นด้วยการแยกวิเคราะห์แหล่งลงใน AST และสิ้นสุดด้วยการสร้างรหัส (โดยทั่วไปสามารถกำหนดค่าใหม่สำหรับแอปพลิเคชันต่าง ๆ ) ทุกขั้นตอนระหว่างดำเนินการต่างๆกับ AST

Partway through เป็นระยะการขยายมาโครซึ่งแมโครจะถูกดำเนินการในบริบทของคอมไพเลอร์ จำบิตในย่อหน้าสุดท้ายเกี่ยวกับการวางท่อได้หรือไม่? หากในระหว่างการขยายแมโครคุณเรียกใช้แมโครที่ล้างไปป์ไลน์จะไม่มีข้อผิดพลาดปรากฏขึ้นกับผู้ใช้ แต่ทุกขั้นตอนหลังจากการขยายแมโคร (รวมถึงการสร้างโค้ด) จะไม่มีอยู่อีกต่อไป ดังนั้นคุณจะจบลงด้วยสิ่งที่ดูเหมือนว่าการรวบรวมที่ประสบความสำเร็จ - ไม่มีข้อความแสดงข้อผิดพลาด - แต่ด้วยเหตุผลบางอย่างไม่มีการผลิตไบนารี! รับประกันว่าคุณจะขับรถได้แม้กระทั่งนักแก้ปัญหาที่ดีที่สุดบนกำแพงหากคุณซ่อนมาโครและการภาวนาได้ดี


คำตอบนี้ไม่ถูกต้องเนื่องจากรหัสผู้ใช้ไม่เคยถูกดำเนินการ
pppery

@ppperry: แน่นอนมันไม่: แมโครสามารถเขียนได้เป็นส่วนหนึ่งของรหัสผู้ใช้และจะดำเนินการภายในของคอมไพเลอร์
Mason Wheeler

คุณจะต้องกำหนดเช่นแมโครสำหรับตัวชุดของตัวละครที่ต้องการที่จะพิมพ์ลงในโปรแกรมเดียวทุกหรือชุดของโปรแกรมที่ทำให้บูพอดีกับเกณฑ์
pppery

@ppperry: ใช่การเรียกใช้แมโคร (ที่ใดก็ได้ในรหัส) เป็นสิ่งที่ทำให้คอมไพเลอร์แตกหักทำให้เป็นไปตามเงื่อนไข หากคุณกำลังพยายามพูดอะไรที่ลึกกว่านั้นคุณจะต้องชัดเจนขึ้นอีกเล็กน้อยเพราะฉันไม่เห็นว่าปัญหาคืออะไร
Mason Wheeler

2
@slebetman: และเมื่อคุณมี REPL หรือมาโครที่มีการใช้งานรหัสผู้ใช้ในเวลารวบรวมความแตกต่างระหว่างทั้งสองจะเบลอมาก
Mason Wheeler

10

NGN / APL

NGN / APL อนุญาตให้กำหนดค่าพื้นฐานได้ดังนั้นการกำหนดใหม่ ( ) ฟังก์ชันดั้งเดิมทั้งหมดเป็น("ผ่าน": ทั้งสอง⊢3และ2⊢3ให้3) ทำให้ภาษาไร้ประโยชน์อย่างสมบูรณ์:

⍪←-←+←?←⍵←∊←⍴←~←↑←↓←⍳←○←*←⌈←⌊←⍕←⊂←⊃←∩←∪←⊥←⊤←|←<←≤←=←≥←>←≠←∨←∧←×←÷←⍒←⍋←⌽←⍉←⊖←⍟←⍱←⍲←!←⌹←⊣←⍎←⊢

ลองที่นี่


1
-1 สำหรับตอนนี้ แต่ดูเหมือนว่าจะมีแนวโน้ม! บางทีถ้าคุณนิยามคำศัพท์ดั้งเดิมทั้งหมด
Blacklight Shining

@ BlacklightShining คุณไปแล้ว
58

8

Ruby (29 ตัวอักษร)

class Object;def send;end;end

ในฐานะที่เป็น 'ส่ง' จะใช้ภายในเมื่อใดก็ตามที่วิธีการที่เรียกว่าภายในทับทิมและเนื่องจากวัตถุทั้งหมดได้รับมรดกจากชั้นวัตถุ นี่ควรหยุดวิธีการใด ๆ ที่กำลังทำงานอยู่

สนุกจริง:นี่คือทฤษฎีเสียงที่สมบูรณ์แบบ แต่มันก็ปรากฏขึ้นด้วยเหตุผลบางอย่างไม่ทำให้ภาษารูบีสั่นคลอน ฉันไม่รู้ว่าทำไมจึงเป็นไปได้ที่จะเรียกใช้รหัสนี้และจากนั้นยังใช้สภาพแวดล้อมแบบเปิดของทับทิม


จริงๆแล้วมันใช้งานได้ในเปลือกPry Ruby
Félix Saparelli

คุณหมายถึงมันทำงานได้ดีใน "สิ่งนี้ทำให้มันแตกสลาย" หรือมันทำงานได้ดีใน "มันยังคงใช้ได้หลังจากนี้"? เฉพาะฉันไม่ได้พูดถึงกรณีที่สองในกรณี irb เก่าธรรมดา
AJFaraday

1
ฉันหมายถึงมันแบ่งแงะ มันไม่ทำลาย IRB และจะไม่หยุดทำงานในไฟล์. rb แต่แบ่ง Pry
Félix Saparelli

น่าสนใจ ฉันเดาว่ามีการป้องกันวิธีการส่งที่ไม่ทำงานในแงะบ้าง
AJFaraday

8

Tcl

foreach x [info commands] {if {$x!="rename"&&$x!="if"} {rename $x ""}}

นี้จะเอาคำหลักทั้งหมดจากภาษายกเว้นและifrename

รหัสด้านบนจะทำให้รหัสใหม่ใด ๆ เกิดข้อผิดพลาด ดังนั้นจึงเป็นที่ถกเถียงกันหากรหัสที่แทรกใหม่จะได้รับ ด้านล่างเป็นรุ่นที่เรียกใช้งานโค้ดใหม่ แต่ไม่ได้ทำอะไรเลยเพราะมันเปลี่ยนคำค้นหาทั้งหมด (ยกเว้นifและproc) เป็นการไม่ทำงาน:

foreach x [info commands] {if {$x!="if"&&$x!="proc"} {
    proc $x args {}
}}

แทนที่จะลบคำหลักรหัสนี้จะแทนที่ด้วยฟังก์ชันที่ไม่ทำอะไรเลย

(หมายเหตุ: ฉันใช้ "คำหลัก" ที่นี่อย่างอิสระเพราะ Tcl ไม่มีคำหลักเฉพาะฟังก์ชั่น)


1
ฉันคิดว่าคุณสามารถทำให้ดีขึ้นได้โดยการเปลี่ยนชื่อifและrenameหลังจากลูป ในรุ่นที่สองคุณควรทำการprocยกเว้น
jimmy23013

@ jimmy23013 อืม .. ในทางเทคนิคแล้วคุณควรจะถูกต้อง แต่ข้อมูลโค้ดนั้นใช้ได้กับ tcl เวอร์ชั่นปัจจุบันแม้procจะปรากฏในรายการก่อนหน้าputsนี้ ในทางเทคนิคแล้วรหัสควรทำงานโดยไม่มีrenameคำสั่งในตัว แต่ดูเหมือนว่าจะได้รับการปกป้อง ไม่แน่ใจว่าเกิดอะไรขึ้น แต่มีการทดสอบรหัสและทำงานตามที่โฆษณาไว้
Slebetman

@ jimmy23013: ตกลง renameรหัสตอนนี้ทำงานโดยไม่จำเป็นต้องโทร มันเป็นการระดมสมองในส่วนของฉัน - ฉันลืมแยกprocออก
Slebetman

ฉันตัดสินใจที่จะไม่เปลี่ยนชื่อifเพราะความสามารถในการทำifคนเดียวนั้นไร้ประโยชน์หากคุณต้องการสร้างผลลัพธ์
Slebetman

แน่นอนคุณไม่จำเป็นต้องเปลี่ยนชื่อพวกเขา แต่นี่ไม่ใช่รหัสกอล์ฟ ฉันแค่คิดว่าการเปลี่ยนชื่อพวกเขาอาจ (หรืออาจไม่) ทำให้คำตอบนี้ดูดีขึ้น
jimmy23013

7

ฮุน

=<  ~
(your code)

ฮุนเป็นคนแปลก มันค่อนข้างแตกต่างจากภาษาการเขียนโปรแกรมอื่น ๆ ไม่เพียง แต่ในรูปแบบไวยากรณ์ แต่เป็นในความหมาย แตกต่างจากภาษาอย่าง Hexagony แต่ก็ไม่ได้ทำให้เกิดความลับอย่างจงใจ

Hoon คอมไพล์ให้กับNockซึ่งเป็น VM แบบคอมบิเนเตอร์ขั้นต่ำ Nock โง่: สเป็คสามารถ gzipped ถึง 340 ไบต์ การดำเนินการทางคณิตศาสตร์เพียงอย่างเดียวเพิ่มขึ้น ทุกอย่างเป็นคำนาม: อะตอม (bignum) หรือเซลล์ (คำนามคู่) โดยมีโมเดลหน่วยความจำทั้งหมดจัดเรียงไว้ในต้นไม้ไบนารี acyclic ที่ไม่เปลี่ยนรูป เอาต์พุตเพียงคำนามที่นิพจน์ของคุณลดลง

เนื่องจากเป้าหมายการรวบรวมแปลก ๆ Hoon ก็แปลกเหมือนกัน: มันบริสุทธิ์อย่างสมบูรณ์ Hoon คอมไพล์ลงในนิพจน์ Nock ที่ประเมินจาก "บริบท" เคอร์เนลและ stdlib ทั้งหมดพร้อมกับตัวแปรทั้งหมดจะถูกส่งผ่านโดยปริยายไปที่โปรแกรมโดยบริบท

เพื่อให้ Hoon ใช้งานไม่ได้เราแค่ใช้=<ซึ่งก็คือ "ประเมิน a ในบริบทของ b" เรามักจะประเมิน~ซึ่งเป็นศูนย์ ไม่ว่าbจะทำอะไรก็ไม่สามารถเปลี่ยนค่าที่ลดลงและเนื่องจากไม่สามารถมีผลข้างเคียงจึงไม่สามารถทำอินพุตหรือเอาต์พุตได้

หมายเหตุด้านข้าง: เนื่องจากคุณไม่สามารถขอให้ป้อนข้อมูลจาก Hoon (ความบริสุทธิ์!) ตามกฎจริงๆแล้วมันไม่ใช่ภาษาโปรแกรม อินพุตคือผ่านอาร์กิวเมนต์ของฟังก์ชันเอาต์พุตผ่านค่าที่ส่งคืน (หรือ~&ซึ่งเป็นคุณสมบัติการดีบัก printf มากกว่าและโปร่งใสต่อโปรแกรม)

เพื่อให้โปรแกรมรับอินพุตใน Urbit คุณเขียนโปรแกรมที่ส่งคืนฟังก์ชันที่รับอินพุตและเชลล์จะถามในนามของคุณและส่งต่อไปยังการโทรกลับ


3
แม้ว่าภาษาการเขียนโปรแกรมตามมาตรฐานของเราแน่นอน
cat

7

แท็กซี่ 2354 ไบต์

โปรแกรมเล็ก ๆ น้อย ๆ นี้ก็วิ่งแท็กซี่ในจอยด์ขนาดใหญ่ผ่าน Townsburg ที่ไม่มีน้ำมัน รหัสใด ๆ error: out of gasที่คุณทำงานหลังจากนี้ได้อย่างรวดเร็วจะมีข้อผิดพลาด และแม้ว่าคุณจะไปถึงปั๊มน้ำมันซึ่งฉันคิดว่าเป็นไปไม่ได้คุณก็ไม่สามารถรับน้ำมันได้เนื่องจากไม่มีเงินเก็บเนื่องจากไม่มีผู้โดยสาร

Go to Trunkers: west, 1st right, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st right, 1st left, 3rd left, 2nd left, 3rd left, 2nd right, 1st right, 2nd right, 1st right, 1st left, 1st left, 1st left, 1st right.

6

JavaScript ในเบราว์เซอร์

อย่างน้อยใน IE11

window.addEventListener("error", function(){});
document = document.write = alert = prompt = confirm = console = void(
    (function (window) {
        try {
            //Code goes here
        } catch (e) {}
    })({})
);

ปิดใช้งานการเขียนไปยังเอกสารเขียนไปยังตัวแปรโกลบอลและส่งคืนจากฟังก์ชัน

แสดงความคิดเห็นหากฉันพลาดวิธีการแสดงผล!


ข้อยกเว้นจะยังคงแสดงในคอนโซล คุณสามารถจัดการกับสิ่งเหล่านั้นได้โดยการทำwindow.addEventListener('error',function(){});
Ismael Miguel

@IsmaelMiguel ตอนนี้ฉันไม่สามารถรับเครดิตทั้งหมดได้! d ;-D
wizzwizz4

4
สิ่งนี้ใช้ได้ผลจริงหรือ ซึ่งไม่สมเหตุสมผลเลย: documentควรยังคงสามารถเข้าถึงได้จากขอบเขตด้านนอกในรหัสที่แทรกและไม่ควรถูกแทนที่จนกว่าจะหลังจากรหัสที่แทรกเสร็จสิ้นการดำเนินการ
Peter Taylor

@PeterTaylor :-( ตรรกะของคุณทำให้ทฤษฎีของฉันแตกสลาย
wizzwizz4


6

Python 2 ใหญ่อย่างเมามัน

import rexec, ihooks, types, os, struct,sys,imp
from functools import update_wrapper as do_update, wraps
__all__ = ["RExec","enable"]
trashed = False
from ctypes import pythonapi, POINTER, py_object
getdict = pythonapi._PyObject_GetDictPtr
getdict.restype = POINTER(py_object)
getdict.argtypes = [py_object]
modified = ctypes.pythonapi.PyType_Modified
modified.argtypes = [ctypes.py_object]
def dictionary_of(ob):
    dptr = getdict(ob)
    if dptr and dptr.contents:
        return dptr.contents.value
RESTRICTED = "NOT AVAILABLE"
class RExec(rexec.RExec):
    ok_sys_names = rexec.RExec.ok_sys_names + ("warnoptions","py3kwarning","flags")
    nok_sys_strings = ("executable",)
    ok_builtin_modules = rexec.RExec.ok_builtin_modules + ("cStringIO","exceptions","_collections","itertools","_hashlib","_codecs","_functools","_struct")
    def __init__(self, hooks = None, verbose = 0):
        ihooks._Verbose.__init__(self, verbose)
        self.hooks = hooks or rexec.RHooks(verbose)
        self.hooks.set_rexec(self)
        self.modules = {}
        self.ok_dynamic_modules = self.ok_builtin_modules
        list = []
        for mname in self.ok_builtin_modules:
            if mname in sys.builtin_module_names:
                list.append(mname)
        self.ok_builtin_modules = tuple(list)
        self.set_trusted_path()
        self.make_builtin()
        self.make_initial_modules()
        self.make_sys()
        self.loader = rexec.RModuleLoader(self.hooks, verbose)
        self.importer = rexec.RModuleImporter(self.loader, verbose)
        self.make_StringIO()
    def make_sys(self):
        old_rexec.make_sys(self)
        sys_ = self.modules["sys"]
        for name in dir(sys):
            obj = getattr(sys,name)
            if "__" not in name and type(obj) == str and \
              not hasattr(sys_,name):
                if name in self.nok_sys_strings:
                    obj = RESTRICTED
                setattr(sys_,name,obj)
        sys_.argv = [RESTRICTED]
    def make_initial_modules(self):
        old_rexec.make_initial_modules(self)
        self.copy_except(types,["__builtins__"])
        self.copy_except(os.path,["__builtins__"])
        b = self.modules["__builtin__"]
        for module in self.modules.itervalues():
            module.__builtins__ = b
    def make_StringIO(self):
        t = type(self.r_open)
        if t == types.ClassType or t == type:
            return
        elif t != types.FunctionType and t != types.MethodType:
            raise RuntimeError
        io = self.r_import("StringIO").StringIO
        old_open = self.r_open
        class r_open(io):
            def __init__(self,*openargs):
                o = old_open(*openargs)
                if o.isatty():raise IOError
                io.__init__(self,o.read())
            def __enter__(self):
                return self
            def __exit__(self,type,val,tb):
                self.close()
            for name in "truncate write flush".split():
                exec "def %s(self,arg=None):raise IOError('File not open for writing')" % name
            del name
        ntypes = self.modules["types"]
        b = self.modules["__builtin__"]
        ntypes.FileType = self.r_open = b.open = b.file = r_open
    def r_import(self,name,globals={},locals={},fromlist=[],level=-1):
        redone = name in self.modules
        found = False
        try:
            result = self.importer.import_module(name, globals, locals, fromlist,level)
        except ImportError:
            if name == "imp":
                result = imp.new_module("imp")
                self.modules["imp"]=result
                found = True
            if not found:raise
        if redone:pass #Only do this once
        elif name == "sysconfig":
            result._PROJECT_BASE = "x"
            result._CONFIG_VARS = {}
        elif name == "functools":
            update = result.update_wrapper
            def update_wrapper(wrapper,wrapped,assigned=(),updated=()):
                return update(wrapper,wrapped,assigned,updated)
            do_update(update_wrapper,update)
            result.update_wrapper = update_wrapper
            def wraps(wrapped,*args,**kw):
                return result.partial(update_wrapper,wrapped=wrapped,*args,**kw)
            do_update(wraps,result.wraps)
            result.wraps = wraps
        return result
    def s_apply(self,func,args=(),kw=None):
        kw = kw or {}
        if getattr(func,"__stdin_trashing",False):
            kw["s_applied"] = True
        return old_rexec.s_apply(self,func,args,kw)
    r_exc_info = staticmethod(sys.exc_info)
    def r_method(name):
        l = {}
        exec \
"""def %s(self,*args,**kwargs):
    s_applied = kwargs.pop("s_applied",False)
    if kwargs:raise TypeError
    if not s_applied:
        self.save_files()
        sys.stdin = sys.stdout = sys.stderr = None
    global restrictedly
    restrictedly = True
    try:
        return old_rexec.%s(self,*args)
    finally:
        restrictedly = False
        if not s_applied:
            self.restore_files()
setattr(%s,"__stdin_trashing",True)""" % (name,name,name) in globals(),l
        return l[name]
    r_exec = r_method("r_exec")
    r_eval = r_method("r_eval")
    del r_method
old_rexec = rexec.RExec
class ModuleImporter(ihooks.ModuleImporter):
    def determine_parent(self, globals, level=-1):
        if not globals or not level:return None
        pkgname = globals.get('__package__')
        if pkgname is not None:
            if not pkgname and level > 0:raise ValueError, 'Attempted relative import in non-package'
        else:
            modname = globals.get('__name__')
            if modname is None:return None
            if "__path__" in globals:pkgname = modname
            else:
                # normal module, work out package name if any
                if '.' not in modname:
                    if level > 0:raise ValueError, ('Attempted relative import in non-package')
                    globals['__package__'] = None
                    return None
                pkgname = modname.rpartition('.')[0]
            globals['__package__'] = pkgname
        if level > 0:
            dot = len(pkgname)
            for x in range(level, 1, -1):
                try:
                    dot = pkgname.rindex('.', 0, dot)
                except ValueError:raise ValueError('attempted relative import beyond top-level package')
            pkgname = pkgname[:dot]
        try:
            return self.modules[pkgname]
        except KeyError:
            if level < 1:
                warn("Parent module '%s' not found while handling "
                     "absolute import" % pkgname, RuntimeWarning, 1)
                return None
            else:raise SystemError, ("Parent module '%s' not loaded, cannot perform relative import" % pkgname)
restrictedly = False
def enable():
    rexec.RExec = RExec
    rexec.RModuleImporter = ModuleImporter
    global trashed
    if not trashed:
        subclasses = type.__subclasses__
        error = None
        def restrict(fun):
            error_ = error
            def censored(*args):
                global restrictedly
                if restrictedly:
                    if error_ is not None:
                        return error_
                    raise RuntimeError
                return fun(*args)
            return censored
        error = ()
        dictionary_of(type)["__subclasses__"]=restrict(subclasses)
        error = None
        modified(type)
        #Stop uses of frames (created using with statements)
        old_frame = types.TracebackType.tb_frame
        @property
        @restrict
        def new_frame(self):
            return old_frame.__get__(self,types.TracebackType)
        @new_frame.setter
        def new_frame(self,v):
            raise TypeError("Readonly attribute")
        dictionary_of(types.TracebackType)["tb_frame"] = new_frame
        modified(types.TracebackType)
        trashed = True
def test():
    enable()
    r = RExec()
    try:
         r.r_exec(
                """Your code goes here!"""
             )
    finally:
        return 0
if __name__ == "__main__":
    enable()
    test()
    sys.exit()

โค้ดจำนวนมากอย่างบ้าคลั่งนี้เป็นการคืนชีพของrexecโมดูลโบราณ(ละทิ้งในไพ ธ อน 2.3) โดยมีโมดูลใหม่เพิ่มเข้ามาในรายการ "ตกลง" และจุดอ่อนจำนวนมากได้รับการแก้ไข (รวมถึงobject.__subclasses__()วิธีการที่ทำให้งูหลามอื่น ๆ คำตอบไม่ถูกต้อง)

ค่อนข้างน้อยของรหัสนี้ ( __init__วิธีการRExecเรียนและทั้งModuleImporterชั้น) จะถูกคัดลอกจากห้องสมุดมาตรฐานหลามกับการปรับเปลี่ยนเล็กน้อย


2
0.o อะ ... คุณทำอะไรไปแล้ว
แมว

8064 bytesโดยวิธีการ
แมว

@ แมวไม่ว่านี่คือรหัสกอล์ฟ ฉันอาจจะเล่นกอล์ฟอย่างน้อย 1,000 ไบต์
pppery

แน่นอน แต่คุณพูดว่า "ใหญ่มาก" ดังนั้นฉันคิดว่าฉันควรทราบ
แมว
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.