Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

138 lines
4.2KB

  1. import binascii
  2. import os
  3. import exec_helpers
  4. import re
  5. import uuid
  6. import json
  7. from flask import request, url_for
  8. from flask_api import FlaskAPI, status, exceptions
  9. from flask_cors import CORS
  10. app = FlaskAPI(__name__)
  11. CORS(app)
  12. @app.route("/compile", methods=['POST'])
  13. def compile():
  14. if request.method == 'POST':
  15. note = str(request.data.get('source', ''))
  16. flags = str(request.data.get('flags', ''))
  17. uuid_ = str(request.data.get('uuid', ''))
  18. if not uuid_:
  19. uuid_ = str(uuid.uuid1())
  20. counter = 0
  21. if os.path.exists("/data/{}/counter".format(uuid_)):
  22. with open("/data/{}/counter".format(uuid_), "r") as f:
  23. counter = int(f.read().strip()) + 1
  24. f.close()
  25. else:
  26. os.mkdir("/data/{}".format(uuid_))
  27. os.mkdir("/data/{}/{}".format(uuid_, counter))
  28. with open("/data/{}/{}/environ".format(uuid_, counter), "w") as f:
  29. for env in os.environ:
  30. f.write("{}={}\n".format(env, os.environ[env]))
  31. f.close()
  32. with open("/data/{}/{}/headers".format(uuid_, counter), "w") as f:
  33. for k, v in request.headers:
  34. f.write("{}: {}\n".format(k, v))
  35. f.close()
  36. with open("/data/{}/{}/source".format(uuid_, counter), "w") as f:
  37. f.write(note)
  38. f.close()
  39. with open("/data/{}/{}/flags".format(uuid_, counter), "w") as f:
  40. f.write(flags)
  41. f.close()
  42. with open("/data/{}/counter".format(uuid_), "w") as f:
  43. f.write(str(counter))
  44. f.close()
  45. with open("/tmp/test.cpp", "w") as f:
  46. f.write(note)
  47. f.close()
  48. stdout = ''
  49. stderr = ''
  50. retcode = 0
  51. output = ''
  52. output_wasm = ''
  53. flags = flags.replace("\n", " ")
  54. wasm = 'cheerp-mode=wasm' in flags
  55. # Simple way to disable malicious flags (hopefully)
  56. if not re.match('^[\s\ta-zA-Z0-9=\-_\.]*$', flags):
  57. flags = ""
  58. cmd = "/opt/cheerp/bin/clang {} /tmp/test.cpp -o /tmp/test.js".format(flags)
  59. if wasm:
  60. cmd = "/opt/cheerp/bin/clang {} /tmp/test.cpp -cheerp-wasm-loader=/tmp/test.js -o /tmp/test.wasm".format(flags)
  61. with exec_helpers.Subprocess() as executor:
  62. try:
  63. ret = executor.check_call(cmd, shell=True, timeout=10)
  64. if ret:
  65. retcode = ret.exit_code
  66. output = ret.stdout_str
  67. except exec_helpers.ExecHelperTimeoutError as e:
  68. #stdout = e.stdout
  69. #stderr = e.stderr
  70. stderr = str(e)
  71. except exec_helpers.CalledProcessError as e:
  72. stdout = e.stdout
  73. stderr = e.stderr
  74. if os.path.exists("/tmp/test.js"):
  75. with open("/tmp/test.js", "r") as f:
  76. output = f.read()
  77. f.close()
  78. if wasm and os.path.exists("/tmp/test.wasm"):
  79. with open("/tmp/test.wasm", "rb") as f:
  80. output_wasm = f.read()
  81. f.close()
  82. return {
  83. 'stdout': stdout,
  84. 'stderr': stderr,
  85. 'command': cmd,
  86. 'retcode': retcode,
  87. 'javascript': output,
  88. 'wasm': binascii.b2a_base64(output_wasm).decode("utf-8") if wasm else "",
  89. 'uuid': uuid_,
  90. 'version': counter,
  91. }, status.HTTP_201_CREATED
  92. @app.route("/retrieve", methods=['POST'])
  93. def retrieve():
  94. if request.method == 'POST':
  95. uuid_ = str(request.data.get('uuid', ''))
  96. version = str(request.data.get('version', ''))
  97. source = ''
  98. flags = ''
  99. if not os.path.exists("/data/{}/{}".format(uuid_, version)):
  100. return False
  101. with open("/data/{}/{}/source".format(uuid_, version), "r") as f:
  102. source = f.read()
  103. f.close()
  104. with open("/data/{}/{}/flags".format(uuid_, version), "r") as f:
  105. flags = f.read()
  106. f.close()
  107. return {
  108. 'source': source,
  109. 'flags': flags,
  110. }, status.HTTP_201_CREATED
  111. if __name__ == "__main__":
  112. app.run(host="0.0.0.0", debug=True)