I have written a function inside PostgreSQL which has the following code:
for (i = 0; i < 4; i++)
{
Datum dat_value = CStringGetDatum(inp->str[0][i]);
values[i] = datumCopy(dat_value,
stats->attrtype->typbyval,
stats->attrtype->typlen);
}
The input strings are {ALGERIA,ARGENTINA,BRAZIL,CANADA}. The code runs for ALGERIA,ARGENTINA but terminates abruptly for BRAZIL. When I investigated I found that inside datumCopy function, the statement after memcpy is not getting printed. I checked if palloc failed with (s == NULL) condition, but that seems to be not the reason. I think memcpy is failing. Any reason why? Thanks!
Datum
datumCopy(Datum value, bool typByVal, int typLen)
{
Datum res;
if (typByVal)
res = value;
else
{
Size realSize;
char *s;
if (DatumGetPointer(value) == NULL)
return PointerGetDatum(NULL);
realSize = datumGetSize(value, typByVal, typLen);
s = (char *) palloc(realSize);
printf ("Value : %s\n",DatumGetPointer(value));
memcpy(s, DatumGetPointer(value), realSize);
printf ("Not printing \n");
res = PointerGetDatum(s);
}
return res;
}
EDITED : Ok this is really wierd. When the input is one of {BRAZIL,PAKISTAN,FRANCE}, the code terminates abruptly. If I have other countries (I haven't tried extensively, but some countries), the code runs correctly.
EDITED 2 : Found the cause and rectified the issue. If we are passing C strings to datumCopy, we have to pass -2 for typLen parameter. I had been passing it incorrectly.
Thanks!
I have found the cause and rectified the issue.
If we are passing C strings to datumCopy, we have to pass -2 for typLen parameter. I had been passing it incorrectly.
Related
I currently try to filter calls to a function by command. I try to do so with the following code where ##REPLACE_comm## is replaced by python by the command name. The double backslash are cause I am using bcc. The following code throws an error when loading:
if(1){
char filter[TASK_COMM_LEN] = "##REPLACE_comm##";
char command[TASK_COMM_LEN];
bpf_get_current_comm(&command, sizeof(command));
for(u16 i = 0; i<=TASK_COMM_LEN; i++){
if(command[i] == '\\0' && filter[i] == '\\0'){
break;
}
if(command[i] == filter[i]){
continue;
}
return 0;
}
}
The error is:
unknown opcode 70
HINT: The 'unknown opcode' can happen if you reference a global or static variable, or data in read-only section. For example, 'char *p = "hello"' will result in p referencing a read-only section, and 'char p[] = "hello"' will have "hello" stored on the stack.
I feel like I already made sure the variables are on the stack by allocating space and not just having a pointer but it doesnt work. What am I missing?
using UnityEngine;
using System.Collections;
public class NewMonoBehaviour1 : MonoBehaviour
{
void ConcatExample(int[] intArray)
{
string line = intArray[0].ToString(); // the line is the var of the first in array
for(i =1;i <intArray.Length; i++) // the length is unknown ?
{
line += ", " + intArray[i].ToString(); //
}
return line;
//each time allocate new in original place
}
}
How can this function work ? the length of array is unknown , so how the for loop works ?Besides, this is void function but shouldn't return anythings right ,or is there any exceptional case ,finally,according to the unity manual, it is said that the function will keep producing a string but with new contents in the same place , resulting in consuming large memory space .Why ?thx
What makes you think that the Length should be unknown? It is a property that any array simply has
Gets the total number of elements in all the dimensions of the Array.
Of course it is not unknown the moment you call your method with an according parameter!
The return line; will not even compile since as you say the method is of type void so it can not return anything. It should probably be private string ConcatExample
Then what the unity manual (don't know where exactly you read this) means lies in
line += ", " + intArray[i].ToString();
under the hood every string in c# is an immutable char[]. So everytime you do a string concatenation via stringC = stringA + stringB what happens under the hood is basically something similar to
char[] stringC = new char[stringA.Length + stringB.Length];
for(var iA = 0; iA < stringA.Length; iA++)
{
stringC[i] = stringA[i];
}
for(var iB = 0; iB < stringB.Length; iB++)
{
stringC[iB + stringA.Length] = stringB[iB];
}
so whenever dealing with loops especially with large data it is strongly recommended to rather use a StringBuilder like
private string ConcatExample(int[] intArray)
{
var builder = new StringBuilder(intArray[0]);
for(i =1; i < intArray.Length; i++)
{
builder.Append(", ").Append(intArray[i].ToString());
}
return builder.ToString();
}
The length of the array will be the length of the array of ints you pass into the function as an argument.
say you pass it
Int[] ints = {1,2,3}
ConcatExample(ints); //the length of the array is now 3
add a debug.log() function to the ConcatExample method
void ConcatExample(int[] intArray)
{
string line = intArray[0].ToString();
for (int i = 1; i < intArray.Length; i++)
{
line += ", " + intArray[i].ToString(); //
Debug.Log(line);
}
}
debug.log would produce the following in the console
1, 2
1, 2, 3
and finally the return line; at the end would just result in an error because yes you are correct void returns nothing
This function CANNOT work, unless it gets the data it expects. A NULL passed to this function, for example, would generate a runtime null-reference exception. Passing a valid integer array, of length zero would generate an invalid index error on the first line.
You are correct, the function returns nothing, and appears pointless. In fact, I would have expected return line; to generate a complier error.
The string type appears "dynamic" meaning, it will indeed allocate more and more memory as needed. Technically, it is actually the string "+" operator, (a function that takes two strings as parameters) that is allocating this space. This function returns a new string, of the appropriate size. The garbage collector will DEallocate "old" strings when they are no longer referenced by any variables.
The question is specific to a pattern that Flawfinder reports:
The snippet
unsigned char child_report;
...
auto readlen = read(pipefd[0], (void *) &child_report, sizeof(child_report));
if(readlen == -1 || readlen != sizeof(child_report)) {
_ret.failure = execute_result::PREIO ; // set some flags to report to the caller
close(pipefd[0]);
return _ret;
}
...
int sec_read = read(pipefd[0], (void *) &child_report, sizeof(child_report));
child_report = 0; // we are not using the read data at all
// we just want to know if the read is successful or not
if (sec_read != 0 && sec_read != -1) { // if success
_ret.failure = execute_result::EXEC; // it means that the child is not able to exec
close(pipefd[0]); // as we set the close-on-exec flag
return _ret; // and we do write after exec in the child
}
I turned out that Codacy (therefore flawfinder) reports such issues on both read:
Check buffer boundaries if used in a loop including recursive loops (CWE-120, CWE-20).
I don't understand.
There is no loop.
In the second case we are not using the read data at all
This is not typical C string, and we don't rely on the ending '\0'
Is there any flaw that I'm not aware of in the code?
I finally conclude this should be a false positive. I check Flawfinder's code and it seems that it is basically doing pattern matching.
https://github.com/david-a-wheeler/flawfinder/blob/293ca17d8212905c7788aca1df7837d4716bd456/flawfinder#L1057
I'm writing an application that requires the user be in a quiet environment. To do this, I periodically check the power reading off the microphone. (I'm aware of the returned value being in dBFS or, in this case, a float in the interval [0, 1]. )
My problem is that the below code works just fine... except when it returns 18466064732283753157623808.00000. I see no NSLog output indicating AudioQueueGetProperty returning a failure. The weird value is always the mentioned value.
-(float)instantaneousPeakPower {
UInt32 dataSize = sizeof(AudioQueueLevelMeterState) * recordFormat.mChannelsPerFrame;
AudioQueueLevelMeterState *levels = (AudioQueueLevelMeterState*)malloc(dataSize);
OSStatus rc = AudioQueueGetProperty(audioQueue, kAudioQueueProperty_CurrentLevelMeter, levels, &dataSize);
if (rc) {
NSLog(#"NoiseLeveMeter>>takeSample - AudioQueueGetProperty(CurrentLevelMeter) returned %#", rc);
}
float channelAvg = 0;
for (int i = 0; i < recordFormat.mChannelsPerFrame; i++) {
channelAvg += levels[i].mPeakPower;
}
free(levels);
// This works because in this particular case one channel always has an mAveragePower of 0.
return channelAvg;
}
What gives? Does the bit pattern of the value perhaps give a clue?
Did you enabled audio level metering?
UInt32 trueValue = true;
AudioQueueSetProperty(audioQueue,kAudioQueueProperty_EnableLevelMetering,&trueValue,sizeof (UInt32));
I am writing an app that ultimately wants to send some XML via email.
I have the mailto/URL thing sussed, thanks to various links on the interweb, including Brandon and Simon Maddox.
So I can send emails with the xml formatted using square brackets ([ ]), rather than the usual angle brackets (< >). But when I send angle brackets, with the XML mangled using the stringByAddingPercentEscapesUsingEncoding call, It treats it as HTML and just prints the values.
If change them to "& lt;" and "& gt;" then it totally strips the XML out... (I know there should not be a space after the & - but the SO formatter turns them into <,>...)
I tried adding some HTML in front to see if that helped, to no avail.
I don't suppose anyone has done this?
Perhaps in-app email is the easy route for me to go... must look into that.
Thanks in advance.
The following code worked for me... I have SIP message data containing <> that needed escaping.
/* remember to call urlEscapeStringDone to free the malloced string.. */
char *urlEscapeString(char *str)
{
int i, l;
char *escStr;
escStr = malloc(strlen(str)*3 + 1);
if(!escStr) return NULL;
memset(escStr, 0, strlen(str)*3);
l = strlen(escStr);
for(i = 0; i < strlen(str); i++)
{
char c = str[i];
/* < and > handling for HTML interpreters.. (apple mail) */
if(c == '<')
{
strcat(escStr, "%26lt%3b");
l += 8;
}
else if(c == '>')
{
strcat(escStr, "%26gt%3b");
l += 8;
}
else if(must_escape(c))
{
char tmp[3];
sprintf(tmp, "%02x", (unsigned) c);
escStr[l] = '%'; l++;
escStr[l] = tmp[0]; l++;
escStr[l] = tmp[1]; l++;
}
else
{
escStr[l] = str[i];
l++;
}
}
printf("escaped: %s\n", escStr);
return escStr;
}
void urlEscapeStringDone(char *str)
{
if(str) free(str);
}
int must_escape(char c)
{
char *allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._";
if(!strchr(allowedChars, c)) return 1;
return 0;
}
Did you try replacing all the '<' and '>' characters with '<' and '>' after you had wrapped it in the basic HTML headers?
As I understand it, this is the usual technique to display XML on a web page.