Browse Source

[uri] Add uri_encode() and uri_decode() functions for URI character encoding

tags/v0.9.4
Michael Brown 16 years ago
parent
commit
b350b10b35
2 changed files with 80 additions and 0 deletions
  1. 78
    0
      src/core/uri.c
  2. 2
    0
      src/include/gpxe/uri.h

+ 78
- 0
src/core/uri.c View File

@@ -26,6 +26,7 @@
26 26
 #include <stdlib.h>
27 27
 #include <string.h>
28 28
 #include <libgen.h>
29
+#include <ctype.h>
29 30
 #include <gpxe/vsprintf.h>
30 31
 #include <gpxe/uri.h>
31 32
 
@@ -381,3 +382,80 @@ struct uri * resolve_uri ( struct uri *base_uri,
381 382
 	free ( tmp_path );
382 383
 	return new_uri;
383 384
 }
385
+
386
+/**
387
+ * Test for unreserved URI characters
388
+ *
389
+ * @v c			Character to test
390
+ * @ret is_unreserved	Character is an unreserved character
391
+ */
392
+static int is_unreserved_uri_char ( int c ) {
393
+	/* According to RFC3986, the unreserved character set is
394
+	 *
395
+	 * A-Z a-z 0-9 - _ . ~
396
+	 */
397
+	return ( isupper ( c ) || islower ( c ) || isdigit ( c ) ||
398
+		 ( c == '-' ) || ( c == '_' ) ||
399
+		 ( c == '.' ) || ( c == '~' ) );
400
+}
401
+
402
+/**
403
+ * URI-encode string
404
+ *
405
+ * @v raw_string	String to be URI-encoded
406
+ * @v buf		Buffer to contain encoded string
407
+ * @v len		Length of buffer
408
+ * @ret len		Length of encoded string (excluding NUL)
409
+ */
410
+size_t uri_encode ( const char *raw_string, char *buf, size_t len ) {
411
+	ssize_t remaining = len;
412
+	size_t used;
413
+	unsigned char c;
414
+
415
+	if ( len )
416
+		buf[0] = '\0';
417
+
418
+	while ( ( c = *(raw_string++) ) ) {
419
+		if ( is_unreserved_uri_char ( c ) ) {
420
+			used = ssnprintf ( buf, remaining, "%c", c );
421
+		} else {
422
+			used = ssnprintf ( buf, remaining, "%%%02X", c );
423
+		}
424
+		buf += used;
425
+		remaining -= used;
426
+	}
427
+
428
+	return ( len - remaining );
429
+}
430
+
431
+/**
432
+ * Decode URI-encoded string
433
+ *
434
+ * @v encoded_string	URI-encoded string
435
+ * @v buf		Buffer to contain decoded string
436
+ * @v len		Length of buffer
437
+ * @ret len		Length of decoded string (excluding NUL)
438
+ */
439
+size_t uri_decode ( const char *encoded_string, char *buf, size_t len ) {
440
+	ssize_t remaining = len;
441
+	char hexbuf[3];
442
+	char *hexbuf_end;
443
+	unsigned char c;
444
+
445
+	if ( len )
446
+		buf[0] = '\0';
447
+
448
+	while ( *encoded_string ) {
449
+		if ( *encoded_string == '%' ) {
450
+			encoded_string++;
451
+			snprintf ( hexbuf, sizeof ( hexbuf ), "%s",
452
+				   encoded_string );
453
+			c = strtoul ( hexbuf, &hexbuf_end, 16 );
454
+			encoded_string += ( hexbuf_end - hexbuf );
455
+		} else {
456
+			c = *(encoded_string++);
457
+		}
458
+		ssnprintf ( buf++, remaining--, "%c", c );
459
+	}
460
+	return ( len - remaining );
461
+}

+ 2
- 0
src/include/gpxe/uri.h View File

@@ -135,5 +135,7 @@ extern char * resolve_path ( const char *base_path,
135 135
 extern struct uri * resolve_uri ( struct uri *base_uri,
136 136
 				  struct uri *relative_uri );
137 137
 extern void churi ( struct uri *uri );
138
+extern size_t uri_encode ( const char *raw_string, char *buf, size_t len );
139
+extern size_t uri_decode ( const char *encoded_string, char *buf, size_t len );
138 140
 
139 141
 #endif /* _GPXE_URI_H */

Loading…
Cancel
Save