C (+ socket), 433 429 280 276 270 259 byte
#define H"medalbot.com"
char**p,B[999],*b=B;main(f){connect(f=socket(2,1,getaddrinfo("www."H,"80",0,&p)),p[4],16);send(f,"GET http://"H"/api/v1/medals HTTP/1.1\r\nHost:"H"\r\n\r\n",69);read(f,b,998);for(f=3;f--;puts(p))b=strchr(p=strstr(++b,"_n")+9,34),*b=0;}
Vì vậy, hóa ra C không giỏi trong việc tải xuống các tài nguyên từ internet và phân tích chúng dưới dạng JSON. Ai biết?
Mã này (tự nhiên) siêu lỏng lẻo với kiểm tra lỗi, vì vậy tôi đoán nếu medalbot.com muốn gửi dữ liệu độc hại thì họ có thể kích hoạt tràn bộ đệm, v.v. Ngoài ra, mã mới nhất mong đợi các giá trị nhất định cho các hằng số (ví dụ AF_INET = 2
) có thể sẽ là trường hợp ở khắp mọi nơi, nhưng nó không được bảo đảm.
Đây là mã ban đầu không quá mong manh (nhưng vẫn không mạnh mẽ hoặc an toàn):
#include<netdb.h>
#define H"medalbot.com"
char*b,*B,d[999];struct addrinfo*p,h;main(f){h.ai_socktype=SOCK_STREAM;getaddrinfo("www."H,"80",&h,&p);f=socket(p->ai_family,p->ai_socktype,p->ai_protocol);connect(f,p->ai_addr,p->ai_addrlen);send(f,"GET http://"H"/api/v1/medals HTTP/1.1\r\nHost: "H":80\r\nConnection: close\r\n\r\n",92,0);recv(f,d,998,0);for(f=0,b=d;f<3;++f)B=strstr(b,"_n")+9,b=strchr(B,'}'),*strchr(B,'"')=0,puts(B);}
Phá vỡ:
// No imports needed whatsoever!
#define H"medalbot.com" // Re-use the host in multiple places
char**p, // This is actually a "struct addrinfo*"
B[999], // The download buffer (global to init with 0)
*b=B; // A mutable pointer to the buffer
main(f){
// Hope for the best: try the first suggested address with no fallback:
// (medalbot.com runs on Heroku which has dynamic IPs, so we must look up the
// IP each time using getaddrinfo)
f=socket(2,1,getaddrinfo("www."H,"80",0,&p));
// 2 = AF_INET
// 1 = SOCK_STREAM
// (may not match getaddrinfo, but works anyway)
// 0 = IP protocol (getaddrinfo returns 0 on success)
connect(f,p[4],16); // struct addrinfo contains a "struct sockaddr" pointer
// which is aligned at 32 bytes (4*8)
// Send the HTTP request (not quite standard, but works. 69 bytes long)
send(f,"GET http://"H"/api/v1/medals HTTP/1.1\r\nHost:"H"\r\n\r\n",69);
// (omit flags arg in send and hope 0 will be assumed)
read(f,b,998); // Get first 998 bytes of response; same as recv(...,0)
// Loop through the top 3 & print country names:
// (p is re-used as a char* now)
for(f=3;f--;puts(p)) // Loop and print:
p=strstr(++b,"_n")+9, // Find "country_name": "
b=strchr(p,34), // Jump to closing "
*b=0; // Set the closing " to \0
}
Điều này không tốt cho máy chủ vì chúng tôi không gửi Connection: close\r\n
như một phần của yêu cầu HTTP. Nó cũng bỏ qua Accept
tiêu đề vì medalbot.com dường như không sử dụng nén trong mọi trường hợp và bỏ lỡ khoảng trống sau Host:
(một lần nữa, máy chủ có vẻ ổn với điều này). Dường như không có gì khác có thể được gỡ bỏ mặc dù.
Khi olympics kết thúc, hành vi có khả năng nhất của chương trình này là segfault cố đọc vị trí bộ nhớ 9. Trừ khi một hacker độc ác chiếm lấy miền, trong trường hợp đó, hành vi rất có thể là để đặt một số byte thành 0 trong địa chỉ thông tin cấu trúc, mà có lẽ không quá nguy hiểm thực sự. Nhưng ai có thể nói với những tin tặc xấu xa này?