diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2015-05-04 17:30:19 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2015-05-04 17:30:19 -0400 |
commit | f5d0d2d35396e46c4e0431d28c6895396f971d20 (patch) | |
tree | 61c69ff3d1229adedbb842dd6724c8d2c8f6d8de | |
parent | 18a80cee75a8bf0dc8fca71238b1e404e6651151 (diff) |
Rewrite urldecode in C
-rw-r--r-- | urldecode.c | 60 | ||||
-rw-r--r-- | urldecode.php | 6 |
2 files changed, 60 insertions, 6 deletions
diff --git a/urldecode.c b/urldecode.c new file mode 100644 index 0000000..fbd39b3 --- /dev/null +++ b/urldecode.c @@ -0,0 +1,60 @@ +/* Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> */ +#include <stdio.h> + +/* ungetc is only guaranteed for 1 char; use our own buffer */ +int buf[2]; +int cnt = 0; +int ab = 0; +int _getchar() { + if (cnt > 0) + cnt--; + else + buf[ab] = getchar(); + int ret = buf[ab]; + ab = !ab; + return ret; +} +void _ungetchar() { + cnt++; + ab = !ab; +} + +int hex(int c) { + if ('0' <= c && c <= '9') + return c - '0'; + if ('A' <= c && c <= 'F') + return 10 + c - 'A'; + if ('a' <= c && c <= 'f') + return 10 + c - 'a'; + return -1; +} + +int +main () { + int c, v1, v2; + while ((c = _getchar()) != EOF) { + switch (c) { + case '%': + if ((v1 = hex(_getchar())) < 0) { + putchar('%'); + _ungetchar(); + continue; + } + if ((v2 = hex(_getchar())) < 0) { + putchar('%'); + _ungetchar(); + _ungetchar(); + continue; + } + putchar(((v1 << 4) & 0xF0) | (v2 & 0x0F)); + break; + case '+': + putchar(' '); + break; + default: + putchar(c); + break; + } + } + return 0; +} diff --git a/urldecode.php b/urldecode.php deleted file mode 100644 index 5d88b9b..0000000 --- a/urldecode.php +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/php -n -<?php -# Copyright (C) 2011, 2014 Luke Shumaker <lukeshu@sbcglobal.net> - -$contents = file_get_contents('php://stdin'); -echo urldecode($contents); |