/** escapes HTML entities * BUG: silently drops entities if there is no room */ void html_escape(char *dest, size_t len, const char *s) { unsigned i; for(i=0;i<len && *s;s++) { switch(*s) { case '<': i+=safe_append(dest+i,len-i, "<"); break; case '>': i+=safe_append(dest+i,len-i, ">"); break; case '&': i+=safe_append(dest+i,len-i, "&"); break; case '"': i+=safe_append(dest+i,len-i, """); break; case '\'': i+=safe_append(dest+i,len-i, "'"); break; default: dest[i++]=*s; } } dest[i]=0; }
// In general, strerror is not async-safe, and therefore we cannot use it directly. So instead we // have to grub through sys_nerr and sys_errlist directly On GNU toolchain, this will produce a // deprecation warning from the linker (!!), which appears impossible to suppress! const char *safe_strerror(int err) { #if defined(__UCLIBC__) // uClibc does not have sys_errlist, however, its strerror is believed to be async-safe. // See issue #808. return strerror(err); #elif defined(HAVE__SYS__ERRS) || defined(HAVE_SYS_ERRLIST) #ifdef HAVE_SYS_ERRLIST if (err >= 0 && err < sys_nerr && sys_errlist[err] != NULL) { return sys_errlist[err]; } #elif defined(HAVE__SYS__ERRS) extern const char _sys_errs[]; extern const int _sys_index[]; extern int _sys_num_err; if (err >= 0 && err < _sys_num_err) { return &_sys_errs[_sys_index[err]]; } #endif // either HAVE__SYS__ERRS or HAVE_SYS_ERRLIST #endif // defined(HAVE__SYS__ERRS) || defined(HAVE_SYS_ERRLIST) int saved_err = errno; static char buff[384]; // use a shared buffer for this case char errnum_buff[64]; format_long_safe(errnum_buff, err); buff[0] = '\0'; safe_append(buff, "unknown error (errno was ", sizeof buff); safe_append(buff, errnum_buff, sizeof buff); safe_append(buff, ")", sizeof buff); errno = saved_err; return buff; }
static int scan_service(char *fn, time_t now, time_t atime) { struct outgoing *o; FILE *f; o = malloc(sizeof(struct outgoing)); if (o) { init_outgoing(o); f = fopen(fn, "r+"); if (f) { if (!apply_outgoing(o, fn, f)) { #if 0 printf("Filename: %s, Retries: %d, max: %d\n", fn, o->retries, o->maxretries); #endif fclose(f); if (o->retries <= o->maxretries) { now += o->retrytime; if (o->callingpid && (o->callingpid == ast_mainpid)) { safe_append(o, time(NULL), "DelayedRetry"); ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn); free_outgoing(o); } else { /* Increment retries */ o->retries++; /* If someone else was calling, they're presumably gone now so abort their retry and continue as we were... */ if (o->callingpid) safe_append(o, time(NULL), "AbortRetry"); safe_append(o, now, "StartRetry"); launch_service(o); } return now; } else { ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt%s\n", o->tech, o->dest, o->retries - 1, ((o->retries - 1) != 1) ? "s" : ""); free_outgoing(o); remove_from_queue(o, "Expired"); return 0; } } else { free_outgoing(o); ast_log(LOG_WARNING, "Invalid file contents in %s, deleting\n", fn); fclose(f); remove_from_queue(o, "Failed"); } } else { free_outgoing(o); ast_log(LOG_WARNING, "Unable to open %s: %s, deleting\n", fn, strerror(errno)); remove_from_queue(o, "Failed"); } } else ast_log(LOG_WARNING, "Out of memory :(\n"); return -1; }
static void *attempt_thread(void *data) { struct outgoing *o = data; int res, reason; if (!ast_strlen_zero(o->app)) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries); res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL); } else { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries); res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL); } if (res) { ast_log(LOG_NOTICE, "Call failed to go through, reason %d\n", reason); if (o->retries >= o->maxretries + 1) { /* Max retries exceeded */ ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt%s\n", o->tech, o->dest, o->retries - 1, ((o->retries - 1) != 1) ? "s" : ""); remove_from_queue(o, "Expired"); } else { /* Notate that the call is still active */ safe_append(o, time(NULL), "EndRetry"); } } else { ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest); ast_log(LOG_EVENT, "Queued call to %s/%s completed\n", o->tech, o->dest); remove_from_queue(o, "Completed"); } free_outgoing(o); return NULL; }
void safe_perror(const char *message) { // Note we cannot use strerror, because on Linux it uses gettext, which is not safe. int err = errno; char buff[384]; buff[0] = '\0'; if (message) { safe_append(buff, message, sizeof buff); safe_append(buff, ": ", sizeof buff); } safe_append(buff, safe_strerror(err), sizeof buff); safe_append(buff, "\n", sizeof buff); write_ignore(STDERR_FILENO, buff, strlen(buff)); errno = err; }
const char *safe_strerror(int err) { if (err >= 0 && err < sys_nerr && sys_errlist[err] != NULL) { return sys_errlist[err]; } else { int saved_err = errno; /* Use a shared buffer for this case */ static char buff[384]; char errnum_buff[64]; format_long_safe(errnum_buff, err); buff[0] = '\0'; safe_append(buff, "unknown error (errno was ", sizeof buff); safe_append(buff, errnum_buff, sizeof buff); safe_append(buff, ")", sizeof buff); errno = saved_err; return buff; } }
void S3_list_bucket(const S3BucketContext *bucketContext, const char *prefix, const char *marker, const char *delimiter, int maxkeys, S3RequestContext *requestContext, const S3ListBucketHandler *handler, void *callbackData) { // Compose the query params string_buffer(queryParams, 4096); string_buffer_initialize(queryParams); #define safe_append(name, value) \ do { \ int fit; \ if (amp) { \ string_buffer_append(queryParams, "&", 1, fit); \ if (!fit) { \ (*(handler->responseHandler.completeCallback)) \ (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ } \ string_buffer_append(queryParams, name "=", \ sizeof(name "=") - 1, fit); \ if (!fit) { \ (*(handler->responseHandler.completeCallback)) \ (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ amp = 1; \ char encoded[3 * 1024]; \ if (!urlEncode(encoded, value, 1024)) { \ (*(handler->responseHandler.completeCallback)) \ (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ string_buffer_append(queryParams, encoded, strlen(encoded), \ fit); \ if (!fit) { \ (*(handler->responseHandler.completeCallback)) \ (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ } while (0) int amp = 0; if (prefix) { safe_append("prefix", prefix); } if (marker) { safe_append("marker", marker); } if (delimiter) { safe_append("delimiter", delimiter); } if (maxkeys) { char maxKeysString[64]; snprintf(maxKeysString, sizeof(maxKeysString), "%d", maxkeys); safe_append("max-keys", maxKeysString); } ListBucketData *lbData = (ListBucketData *) malloc(sizeof(ListBucketData)); if (!lbData) { (*(handler->responseHandler.completeCallback)) (S3StatusOutOfMemory, 0, callbackData); return; } simplexml_initialize(&(lbData->simpleXml), &listBucketXmlCallback, lbData); lbData->responsePropertiesCallback = handler->responseHandler.propertiesCallback; lbData->listBucketCallback = handler->listBucketCallback; lbData->responseCompleteCallback = handler->responseHandler.completeCallback; lbData->callbackData = callbackData; string_buffer_initialize(lbData->isTruncated); string_buffer_initialize(lbData->nextMarker); initialize_list_bucket_data(lbData); // Set up the RequestParams RequestParams params = { HttpRequestTypeGET, // httpRequestType { bucketContext->hostName, // hostName bucketContext->bucketName, // bucketName bucketContext->protocol, // protocol bucketContext->uriStyle, // uriStyle bucketContext->accessKeyId, // accessKeyId bucketContext->secretAccessKey, // secretAccessKey bucketContext->securityToken }, // securityToken 0, // key queryParams[0] ? queryParams : 0, // queryParams 0, // subResource 0, // copySourceBucketName 0, // copySourceKey 0, // getConditions 0, // startByte 0, // byteCount 0, // putProperties &listBucketPropertiesCallback, // propertiesCallback 0, // toS3Callback 0, // toS3CallbackTotalSize &listBucketDataCallback, // fromS3Callback &listBucketCompleteCallback, // completeCallback lbData // callbackData }; // Perform the request request_perform(¶ms, requestContext); }
static STSStatus compose_post_data(char* buffer, uint32_t bufferSize, CommonRequestContext* commonContext, AssumeRoleRequestContext* assumeRoleContext) { string_buffer(queryParams, 2048*3); string_buffer_initialize(queryParams); char* queryParamsArray[32]; int paramsCount = 0; int len = 0; int start = 0; int amp = 0; #define safe_append(isNewParam, name, value) \ do { \ int fit; \ start = len; \ if (amp) { start++; } \ if (isNewParam) { \ queryParamsArray[paramsCount++] = &(queryParams[start]); \ } \ if (amp) { \ string_buffer_append(queryParams, "&", 1, fit); \ if (!fit) { \ return STSStatusUriTooLong; \ } \ len++; \ } \ string_buffer_append(queryParams, name "=", \ sizeof(name "=") - 1, fit); \ if (!fit) { \ return STSStatusUriTooLong; \ } \ len += strlen(name) + 1; \ amp = 1; \ string_buffer_append(queryParams, value, strlen(value), fit); \ len += strlen(value); \ } while (0) time_t now = time(NULL); char timebuf[256]; strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); STSUUID uuid; char* uuidString; uuid_create(&uuid); uuid_to_string(&uuid, &uuidString); char durationSeconds[10]; snprintf(durationSeconds, 10, "%d", assumeRoleContext->durationSeconds); safe_append(1, "Format", "JSON"); safe_append(1, "Version", "2015-04-01"); safe_append(1, "SignatureVersion", "1.0"); safe_append(1, "SignatureMethod", "HMAC-SHA1"); safe_append(1, "SignatureNonce", uuidString); safe_append(1, "Timestamp", timebuf); safe_append(1, "Action", commonContext->action); safe_append(1, "AccessKeyId", commonContext->accessKeyId); safe_append(1, "RoleArn", assumeRoleContext->RoleArn); safe_append(1, "RoleSessionName", assumeRoleContext->RoleSessionName); safe_append(1, "Policy", assumeRoleContext->policy); safe_append(1, "DurationSeconds", durationSeconds); params_array_sort(queryParamsArray, paramsCount); string_buffer(signature, 256); string_buffer_initialize(signature); compute_signature(signature, 256, queryParamsArray, paramsCount, commonContext->accessKeySecret); compose_url_encoded_post_data(buffer, bufferSize, queryParams, strlen(queryParams), signature); free(uuidString); return STSStatusOK; }
void S3_list_parts(S3BucketContext *bucketContext, const char *key, const char *partnumbermarker, const char *uploadid, const char *encodingtype, int maxparts, S3RequestContext *requestContext, const S3ListPartsHandler *handler, void *callbackData) { // Compose the query params string_buffer(queryParams, 4096); string_buffer_initialize(queryParams); #define safe_append(name, value) \ do { \ int fit; \ if (amp) { \ string_buffer_append(queryParams, "&", 1, fit); \ if (!fit) { \ (*(handler->responseHandler.completeCallback)) \ (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ } \ string_buffer_append(queryParams, name "=", \ sizeof(name "=") - 1, fit); \ if (!fit) { \ (*(handler->responseHandler.completeCallback)) \ (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ amp = 1; \ char encoded[3 * 1024]; \ if (!urlEncode(encoded, value, 1024)) { \ (*(handler->responseHandler.completeCallback)) \ (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ string_buffer_append(queryParams, encoded, strlen(encoded), \ fit); \ if (!fit) { \ (*(handler->responseHandler.completeCallback)) \ (S3StatusQueryParamsTooLong, 0, callbackData); \ return; \ } \ } while (0) char subResource[512]; snprintf(subResource, 512, "uploadId=%s", uploadid); int amp = 0; if (partnumbermarker && *partnumbermarker) { safe_append("part-number-marker", partnumbermarker); } if (encodingtype && *encodingtype) { safe_append("encoding-type", encodingtype); } if (maxparts) { char maxPartsString[64]; snprintf(maxPartsString, sizeof(maxPartsString), "%d", maxparts); safe_append("max-parts", maxPartsString); } ListPartsData *lpData = (ListPartsData *) malloc(sizeof(ListPartsData)); if (!lpData) { (*(handler->responseHandler.completeCallback)) (S3StatusOutOfMemory, 0, callbackData); return; } simplexml_initialize(&(lpData->simpleXml), &listPartsXmlCallback, lpData); lpData->responsePropertiesCallback = handler->responseHandler.propertiesCallback; lpData->listPartsCallback = handler->responseXmlCallback; lpData->responseCompleteCallback = handler->responseHandler.completeCallback; lpData->callbackData = callbackData; string_buffer_initialize(lpData->isTruncated); string_buffer_initialize(lpData->nextPartNumberMarker); string_buffer_initialize(lpData->initiatorId); string_buffer_initialize(lpData->initiatorDisplayName); string_buffer_initialize(lpData->ownerId); string_buffer_initialize(lpData->ownerDisplayName); string_buffer_initialize(lpData->storageClass); initialize_list_parts_data(lpData); lpData->handlePartsStart = 0; // Set up the RequestParams RequestParams params = { HttpRequestTypeGET, // httpRequestType { bucketContext->hostName, // hostName bucketContext->bucketName, // bucketName bucketContext->protocol, // protocol bucketContext->uriStyle, // uriStyle bucketContext->accessKeyId, // accessKeyId bucketContext->secretAccessKey, // secretAccessKey bucketContext->securityToken }, // securityToken key, // key queryParams[0] ? queryParams : 0, // queryParams subResource, // subResource 0, // copySourceBucketName 0, // copySourceKey 0, // getConditions 0, // startByte 0, // byteCount 0, // putProperties &listPartsPropertiesCallback, // propertiesCallback 0, // toS3Callback 0, // toS3CallbackTotalSize &listPartsDataCallback, // fromS3Callback &listPartsCompleteCallback, // completeCallback lpData // callbackData }; // Perform the request request_perform(¶ms, requestContext); }
int svg_to_ps(lua_State *L) { const char* input = luaL_checkstring(L, 1); int em = 72; if (lua_gettop(L) == 2) { em = luaL_checkinteger(L, 2); } struct NSVGimage* image; image = nsvgParse((char*)input, "pt", em); int max_output = 256; int output_l = 0; char *output = malloc(max_output); output[0] = '\0'; for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) { for (NSVGpath *path = shape->paths; path != NULL; path = path->next) { double lastx = -1; double lasty = -1; for (int i = 0; i < path->npts-1; i += 3) { float* p = &path->pts[i*2]; char thisPath[256]; // Some kind of precision here? if (lastx != p[0] || lasty != p[1]) { // Move needed snprintf(thisPath, 256, "%f %f m ", p[0], p[1]); output = safe_append(output, &output_l, &max_output, thisPath); } snprintf(thisPath, 256, "%f %f %f %f %f %f c ", p[2],p[3], p[4],p[5], p[6],p[7]); lastx = p[6]; lasty = p[7]; output = safe_append(output, &output_l, &max_output, thisPath); } char strokeFillOper = 's'; // Just stroke if (!path->closed) strokeFillOper = 'S'; if (shape->stroke.type == NSVG_PAINT_COLOR) { int r = shape->stroke.color & 0xff; int g = (shape->stroke.color >> 8) & 0xff; int b = (shape->stroke.color >> 16)& 0xff; char color[256]; snprintf(color, 256, "%f w %f %f %f RG ", shape->strokeWidth, r/256.0, g/256.0, b/256.0); output = safe_append(output, &output_l, &max_output, color); } if (shape->fill.type == NSVG_PAINT_COLOR) { int r = shape->fill.color & 0xff; int g = (shape->fill.color >> 8) & 0xff; int b = (shape->fill.color >> 16)& 0xff; char color[256]; snprintf(color, 256, "%f %f %f rg ", r/256.0, g/256.0, b/256.0); output = safe_append(output, &output_l, &max_output, color); strokeFillOper = 'f'; if (shape->stroke.type == NSVG_PAINT_COLOR) { strokeFillOper = 'B'; } else { if (output_l + 2 > max_output) { output = realloc(output, max_output + 2); } output[output_l++] = 'h'; output[output_l++] = ' '; } } if (output_l + 3 > max_output) { output = realloc(output, max_output + 3); } output[output_l++] = strokeFillOper; output[output_l++] = ' '; output[output_l] = '\0'; }