Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[uri] Add uri_encode() and uri_decode() functions for URI character e…
…ncoding
  • Loading branch information
Michael Brown committed Sep 24, 2008
1 parent 9d44a06 commit b350b10
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
78 changes: 78 additions & 0 deletions src/core/uri.c
Expand Up @@ -26,6 +26,7 @@
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#include <ctype.h>
#include <gpxe/vsprintf.h>
#include <gpxe/uri.h>

Expand Down Expand Up @@ -381,3 +382,80 @@ struct uri * resolve_uri ( struct uri *base_uri,
free ( tmp_path );
return new_uri;
}

/**
* Test for unreserved URI characters
*
* @v c Character to test
* @ret is_unreserved Character is an unreserved character
*/
static int is_unreserved_uri_char ( int c ) {
/* According to RFC3986, the unreserved character set is
*
* A-Z a-z 0-9 - _ . ~
*/
return ( isupper ( c ) || islower ( c ) || isdigit ( c ) ||
( c == '-' ) || ( c == '_' ) ||
( c == '.' ) || ( c == '~' ) );
}

/**
* URI-encode string
*
* @v raw_string String to be URI-encoded
* @v buf Buffer to contain encoded string
* @v len Length of buffer
* @ret len Length of encoded string (excluding NUL)
*/
size_t uri_encode ( const char *raw_string, char *buf, size_t len ) {
ssize_t remaining = len;
size_t used;
unsigned char c;

if ( len )
buf[0] = '\0';

while ( ( c = *(raw_string++) ) ) {
if ( is_unreserved_uri_char ( c ) ) {
used = ssnprintf ( buf, remaining, "%c", c );
} else {
used = ssnprintf ( buf, remaining, "%%%02X", c );
}
buf += used;
remaining -= used;
}

return ( len - remaining );
}

/**
* Decode URI-encoded string
*
* @v encoded_string URI-encoded string
* @v buf Buffer to contain decoded string
* @v len Length of buffer
* @ret len Length of decoded string (excluding NUL)
*/
size_t uri_decode ( const char *encoded_string, char *buf, size_t len ) {
ssize_t remaining = len;
char hexbuf[3];
char *hexbuf_end;
unsigned char c;

if ( len )
buf[0] = '\0';

while ( *encoded_string ) {
if ( *encoded_string == '%' ) {
encoded_string++;
snprintf ( hexbuf, sizeof ( hexbuf ), "%s",
encoded_string );
c = strtoul ( hexbuf, &hexbuf_end, 16 );
encoded_string += ( hexbuf_end - hexbuf );
} else {
c = *(encoded_string++);
}
ssnprintf ( buf++, remaining--, "%c", c );
}
return ( len - remaining );
}
2 changes: 2 additions & 0 deletions src/include/gpxe/uri.h
Expand Up @@ -135,5 +135,7 @@ extern char * resolve_path ( const char *base_path,
extern struct uri * resolve_uri ( struct uri *base_uri,
struct uri *relative_uri );
extern void churi ( struct uri *uri );
extern size_t uri_encode ( const char *raw_string, char *buf, size_t len );
extern size_t uri_decode ( const char *encoded_string, char *buf, size_t len );

#endif /* _GPXE_URI_H */

0 comments on commit b350b10

Please sign in to comment.