C (+ soket), 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;}
Jadi ternyata C tidak hebat dalam mengunduh sumber daya dari internet dan menguraikannya sebagai JSON. Siapa yang tahu?
Kode ini (tentu saja) super longgar dengan pengecekan kesalahan, jadi saya kira jika medalbot.com ingin mengirim data berbahaya mereka akan dapat memicu buffer overflows, dll. Juga kode terbaru mengharapkan nilai-nilai tertentu untuk konstanta (misalnya AF_INET = 2
) yang akan mungkin terjadi di mana-mana, tapi itu tidak dijamin.
Berikut kode asli yang tidak terlalu rapuh (tapi masih tidak terlalu kuat atau aman):
#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);}
Kerusakan:
// 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
}
Ini tidak terlalu baik untuk server karena kami tidak mengirim Connection: close\r\n
sebagai bagian dari permintaan HTTP. Itu juga menghilangkan Accept
header karena medalbot.com tampaknya tidak menggunakan kompresi dalam hal apa pun, dan melewatkan ruang setelah Host:
(sekali lagi, server tampaknya baik-baik saja dengan ini). Sepertinya tidak ada hal lain yang bisa dihapus.
Setelah olimpiade berakhir, perilaku yang paling mungkin untuk program ini adalah untuk segfault mencoba membaca lokasi memori. info struct, yang mungkin sebenarnya tidak terlalu berbahaya. Tapi siapa yang bisa tahu dengan peretas jahat ini?