I am trying to make a CUPS print system. I want to get printer status, how many pages printed sofar etc.
To do that, I am executing example programs given in CUPS examples.
#include <cups/cups.h>
#include <stdio.h>
int main(){
int num_options;
cups_option_t *options;
cups_dest_t *dests;
int num_dests = cupsGetDests(&dests);
cups_dest_t *dest = cupsGetDest("name", NULL, num_dests, dests);
int job_id;
/* Print a single file */
job_id = cupsPrintFile(dest->name, "testfile.txt", "Test Print", num_options, options);
cupsFreeDests(num_dests, dests);
return 0;
}
I compile it using gcc myfile.c -o myout -lcups
When I try to execute ./myout
I am getting
Segmentation fault
I am using Raspberry-pi 3 board as my CUPS server.
Thanks in advance.
dest is pointing to non-valid address.
cups_dest_t *dest; // declared but not initialized or assigned afterwards
So dereferencing it ( cupsPrintFile(dest->name... ) is UB and can cause SegFault.
This is how you should have used it (taken from here):
#include <cups/cups.h>
cups_dest_t *dests;
int num_dests = cupsGetDests(&dests);
cups_dest_t *dest = cupsGetDest("name", NULL, num_dests, dests);
/* do something with dest */
cupsFreeDests(num_dests, dests);
Update:
Your code doesn't handle some of the variables (i.e. leaves them uninitialized - bad). The first one I see is cups_option_t *options;. Take care of all of your variables, and if that's not working - debug.
int main(){
int num_options;
cups_option_t *options; // add a call to "cupsAddOption("first", "value", num_options, &options);"
cups_dest_t *dests;
int num_dests = cupsGetDests(&dests);
cups_dest_t *dest = cupsGetDest("name", NULL, num_dests, dests);
int job_id;
/* Print a single file */
job_id = cupsPrintFile(dest->name, "testfile.txt", "Test Print", num_options, options); // options is used here but is uninitialized
cupsFreeDests(num_dests, dests);
return 0;
}
Related
Heres my main.c:
int main() {
char *x = "add r3,r5";
char *t;
char **end;
t = getFirstTok(x,end);
printf("%s",t);
}
And the function getFirstTok:
/* getFirstTok function returns a pointer to the start of the first token. */
/* Also makes *endOfTok (if it's not NULL) to point at the last char after the token. */
char *getFirstTok(char *str, char **endOfTok)
{
char *tokStart = str;
char *tokEnd = NULL;
/* Trim the start */
trimLeftStr(&tokStart);
/* Find the end of the first word */
tokEnd = tokStart;
while (*tokEnd != '\0' && !isspace(*tokEnd))
{
tokEnd++;
}
/* Add \0 at the end if needed */
if (*tokEnd != '\0')
{
*tokEnd = '\0';
tokEnd++;
}
/* Make *endOfTok (if it's not NULL) to point at the last char after the token */
if (endOfTok)
{
*endOfTok = tokEnd;
}
return tokStart;
}
Why do i get segmentation fault running this main program?
I'm programming a two pass aseembler and i need a function that get parse a string by a delimiter, In this case a white space. Is it better to use strtok instead for this purpose?
I need a command pasrer - So that it will extract "add", an operand parser (By , delimiter), To extract "r3" and "r5". I wanted to check if this getFirstTok function is good for this purpose but when i try to run it i get a segmentation fault:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
Thank you.
As pointed out in the comments, string literals are read-only, as they are baked into the compiled program. If you don't want to go with the suggested solution of making your "source program" a stack-allocated array of characters (char x[] = "add r3,r5"), you can use a function like strdup(3) to make a readable/writable copy like so:
#include <string.h>
[...]
char *rw_code = strdup(x);
t = getFirstTok(rw_code, end);
printf("%s", t);
free(rw_code); /* NOTE: invalidates _all_ references pointing at it! */
[...]
And as a little aside, I always make string literals constant const char *lit = "...", as the compiler will usually warn me if I attempt to write to them later on.
I'm trying to encrypt a message using the ECDSA algorithm with OpenSSL (1.1.1), but I must be doing something wrong with my pointers, because everytime I run the code, it gives me a different result.
Here's what I do:
create a key using custom curve parameters (with BN_hex2bn);
sign a simple message using ECDSA_do_sign;
split the message into the R and S points (ECDSA_SIG_get0_r and ECDSA_SIG_get0_s);
display the resulting R point.
And the display value is always different, while I expect it to be the same (because same message and same key). I think some memory is deallocated somewhere, giving me a pointer to invalid data, but I'm not sure about it; I have checked:
the keys are ok, and they are valid according to EC_KEY_check_key;
the two variables s and r are already wrong, hence it doesn't come from BN_bn2bin.
Here is my code if you want to give a try:
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/ecdsa.h>
#include <openssl/buffer.h>
int main(void) {
ECDSA_SIG *sig;
EC_KEY *eckey;
BIGNUM *priv_key = BN_new();
BIGNUM *x_key = BN_new();
BIGNUM *y_key = BN_new();
const char digest[] = "Hello, world!";
eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
// Set predefined keys
BN_hex2bn(&priv_key, "8e9b109e719098bf980487df1f5d77e9cb29606ebed2263b5f57c213df84f4b2");
BN_hex2bn(&x_key, "7fcdce2770f6c45d4183cbee6fdb4b7b580733357be9ef13bacf6e3c7bd15445");
BN_hex2bn(&y_key, "c7f144cd1bbd9b7e872cdfedb9eeb9f4b3695d6ea90b24ad8a4623288588e5ad");
EC_KEY_set_private_key(eckey, priv_key);
EC_KEY_set_public_key_affine_coordinates(eckey, x_key, y_key);
sig = ECDSA_do_sign(digest, 32, eckey);
// Get the resulting point
const BIGNUM *r = ECDSA_SIG_get0_r(sig);
const BIGNUM *s = ECDSA_SIG_get0_s(sig);
unsigned char rc[256];
unsigned char sc[256];
BN_bn2bin(r, rc);
BN_bn2bin(s, sc);
// Print the result: some memory problem...
for(int i = 0; rc[i] != 0; i++) {
printf("%d ", rc[i]);
}
return 0;
}
Do no forget to link the libraries when you compile it: gcc -g -o main main.c -lssl -lcrypto.
I found this code on the internet:
#include <string.h>
#include <malloc.h>
#include <espeak/speak_lib.h>
espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 1000, Options=0;
void* user_data;
t_espeak_callback *SynthCallback;
espeak_PARAMETER Parm;
char Voice[] = {"English"};
char text[30] = {"this is a english test"};
unsigned int Size,position=0, end_position=0, flags=espeakCHARS_AUTO, *unique_identifier;
int main(int argc, char* argv[] )
{
output = AUDIO_OUTPUT_PLAYBACK;
int I, Run = 1, L;
espeak_Initialize(output, Buflength, path, Options );
espeak_SetVoiceByName(Voice);
const char *langNativeString = "en"; //Default to US English
espeak_VOICE voice;
memset(&voice, 0, sizeof(espeak_VOICE)); // Zero out the voice first
voice.languages = langNativeString;
voice.name = "US";
voice.variant = 2;
voice.gender = 1;
espeak_SetVoiceByProperties(&voice);
Size = strlen(text)+1;
espeak_Synth( text, Size, position, position_type, end_position, flags,
unique_identifier, user_data );
espeak_Synchronize( );
return 0;
}
I only want the espeak reads my strings in my program, and the above code can do it, but I want to know, are all of this code necessary for that purpose? (I mean is it possible to simplifying it?)
***Also I like to know are there a way to using espeak as a system function? I mean system("espeak "something" "); ?
The usage of eSpeak itself seems pretty minimal - you need to read the documentation for that. There are some minor C coding simplifications possible, but perhaps hardly worth the effort:
The memset() is unnecessary. The structure can be initialised to zero thus:
espeak_VOICE voice = {0} ;
If you declare text thus:
char text[] = "this is a English test";
Then you can avoid using strlen() and replace Size with sizeof(text).
The variables I, Run and L are unused and can be removed.
To be able to pass the text as a string on the command line, and thus be able to issue system( "espeak \"Say Something\"") ; for example, you simply need to pass argv[1] to espeak_Synth() instead of text (but you will need to reinstate the strlen() call to get the size.
I am using this library for libgps and having a few issues with it getting it to run properly.
The error from my debugger after it says segfault is:
Cannot find bounds of current function
The line of code throwing this is located in this file, on line 132.
uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16);
I don't know the context of this at all, and I dont know why it would / wouldn't throw a segfault.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <gps.h>
#include <math.h>
/*
*
*/
int main(int argc, char** argv) {
// Open
gps_init();
gps_on();
loc_t data;
gps_location(&data);
printf("%lf %lf\n", data.latitude, data.longitude);
return (EXIT_SUCCESS);
}
The function gps_location() takes you into gps.c and from there it runs into serial.c, once it runs:
void serial_readln(char *buffer, int len)
{
char c;
char *b = buffer;
int rx_length = -1;
while(1) {
rx_length = read(uart0_filestream, (void*)(&c), 1);
if (rx_length <= 0) {
//wait for messages
sleep(1);
} else {
if (c == '\n') {
*b++ = '\0';
break;
}
*b++ = c;
}
}
}
On the break it returns to gps.c goes into:
switch (nmea_get_message_type(buffer)) {
which takes it into nmea.c for nmea_get_message_type above.
It then runs the line:
if ((checksum = nmea_valid_checksum(message)) != _EMPTY)
taking it down to: uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16); which is where the error is.
What is causing this?
Edit:
uint8_t is defined as: typedef unsigned char uint8_t;
Segmentation fault is not a "thrown exception" per se, it is a hardware-issued problem ("you said go there, but I don't see anything named 'there'").
As for your problem: what happens when strchr() does not find the specified character? I suggest you try it and find out.
The code you are working with is horrible and has no error checking anywhere. So it may go haywire for any unexpected input. This could be a potential security vulnerability too.
To fix this particular instance, change the code to:
if ( !message )
return NMEA_CHECKSUM_ERR; // possibly `exit` or something, this shouldn't happen
char *star = strchr(message, '*');
if ( !star )
return NMEA_CHECKSUM_ERR;
uint8_t checksum = strtol(star, NULL, 16);
The nmea_parse_gpgga and nmea_parse_gprmc also have multiple instances of a similar problem.
These functions might be acceptable if there was a parser or a regexp check that sanitizes the input before calling these functions. However, based on your question (I didn't check the codebase), it seems data is passed directly from read which is inexcusable.
The segfaulting function was not designed to handle an empty message or in fact any message not matching the expected form.
Another disastrous blunder is that the serial_readln function never checks that it does not write beyond len.
I've got some code which generates an array of strings of different file names and then
passes them into a function to write some data to them. It adds a incrementing number to the starting filename which is supplied from an input argument.
The problem is that it works fine running from source in Visual Studio 2012 but when I compile it and run it as an .exe the program crashes.
The .exe doesn't appear to be passing the array of strings properly which is causing an error when it attempts to use the string
for opening a file etc.
Here is the isolated bit of code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <Windows.h>
void processing_function(int num_output, char **outnames)
{
/* in Visual Studio this works fine and prints all
the names correctly. Running from .exe will crash */
for(int idx = 0; idx <num_output;idx++)
{
printf("outnames[%d] is %s\n",idx,outnames[idx]);
}
}
int main(int argc, char *argv[])
{
/*nframes comes from another function, outname comes from input arguement */
int num_output = ceil(((double)*nframes / 1100));
int outname_len = strlen(outname)+1;
char *out_right;
out_right = (char*) malloc(sizeof(char)*outname_len);
/*Split string to append numbers before file extension */
strcpy(out_right,outname);
strrev(out_right);
strtok(out_right,".");
strcat(out_right,".");
strrev(out_right);
int out_right_len = strlen(out_right);
strtok(outname,".");
strcat(outname,"-");
int out_origlen = strlen(outname);
int num_len = 1;
char **outnames;
char *num;
char *outname_tmp;
outnames = (char**) malloc(sizeof(char)*(num_output));
int out_len;
double dbl_idx;
int *numfs = (int*)malloc(sizeof(int)*num_output);
for(int idx = 1;idx <num_output+1;idx++)
{
/*convert output number to string and stitch complete name back together and place into array */
num_len = ceil(log10((double)idx+0.1));
num = (char*) malloc(sizeof(char)*(num_len+1));
outname_tmp = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outname_tmp,outname);
sprintf(num,"%d",idx);
strcat(outname_tmp,num);
free(num);
strcat(outname_tmp,out_right);
outnames[idx-1] = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outnames[idx-1],outname_tmp);
free(outname_tmp);
printf("%s\n",outnames[idx-1]);
}
free(out_right);
processing_function(num_ouput, outnames)
return(0);
}
EDIT: Changed num_input to num_output as they do have the same value.
Running from .exe will sometimes start printing some of the names and then crash, opening the
debugger gives an error within output.c, with an access reading violation. I tried putting this code at
the top of the processing_function but that gave further problems downstream (heap corruption), which makes me think that the
code is messing up the memory but I can't see whats wrong with it, nor why it would work in VS but not as a .exe.
I could try and dodge the issue by generating the next output name on the fly every time it requires one but I'd really rather know why this isn't working.
Any help would be greatly appreciated.
I am going to take a shot and say, you passed num_input to processing_function() with outnames, outnames was allocated with num_output for size, but num_input and num_output have different values at runtime. So that lets processing_function() access out of bounds.