1/* 2 * validate.c: validation routines 3 * 4 * ==================================================================== 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 * ==================================================================== 22 */ 23 24/* ==================================================================== */ 25 26 27 28/*** Includes. ***/ 29 30#define APR_WANT_STRFUNC 31#include <apr_want.h> 32 33#include "svn_error.h" 34#include "svn_ctype.h" 35#include "svn_private_config.h" 36 37 38 39/*** Code. ***/ 40 41svn_error_t * 42svn_mime_type_validate(const char *mime_type, apr_pool_t *pool) 43{ 44 /* Since svn:mime-type can actually contain a full content type 45 specification, e.g., "text/html; charset=UTF-8", make sure we're 46 only looking at the media type here. */ 47 const apr_size_t len = strcspn(mime_type, "; "); 48 const apr_size_t len2 = strlen(mime_type); 49 const char *const slash_pos = strchr(mime_type, '/'); 50 apr_size_t i; 51 const char *tspecials = "()<>@,;:\\\"/[]?="; 52 53 if (len == 0) 54 return svn_error_createf 55 (SVN_ERR_BAD_MIME_TYPE, NULL, 56 _("MIME type '%s' has empty media type"), mime_type); 57 58 if (slash_pos == NULL || slash_pos >= &mime_type[len]) 59 return svn_error_createf 60 (SVN_ERR_BAD_MIME_TYPE, NULL, 61 _("MIME type '%s' does not contain '/'"), mime_type); 62 63 /* Check the mime type for illegal characters. See RFC 1521. */ 64 for (i = 0; i < len; i++) 65 { 66 if (&mime_type[i] != slash_pos 67 && (! svn_ctype_isascii(mime_type[i]) 68 || svn_ctype_iscntrl(mime_type[i]) 69 || svn_ctype_isspace(mime_type[i]) 70 || (strchr(tspecials, mime_type[i]) != NULL))) 71 return svn_error_createf 72 (SVN_ERR_BAD_MIME_TYPE, NULL, 73 _("MIME type '%s' contains invalid character '%c' " 74 "in media type"), 75 mime_type, mime_type[i]); 76 } 77 78 /* Check the whole string for unsafe characters. (issue #2872) */ 79 for (i = 0; i < len2; i++) 80 { 81 if (svn_ctype_iscntrl(mime_type[i]) && mime_type[i] != '\t') 82 return svn_error_createf( 83 SVN_ERR_BAD_MIME_TYPE, NULL, 84 _("MIME type '%s' contains invalid character '0x%02x' " 85 "in postfix"), 86 mime_type, mime_type[i]); 87 } 88 89 return SVN_NO_ERROR; 90} 91 92 93svn_boolean_t 94svn_mime_type_is_binary(const char *mime_type) 95{ 96 /* See comment in svn_mime_type_validate() above. */ 97 const apr_size_t len = strcspn(mime_type, "; "); 98 return ((strncmp(mime_type, "text/", 5) != 0) 99 && (len != 15 || strncmp(mime_type, "image/x-xbitmap", len) != 0) 100 && (len != 15 || strncmp(mime_type, "image/x-xpixmap", len) != 0) 101 ); 102} 103