Passing array as function parameters in PHP7.0 - php-7

I have a function as follows:
/**
* #param \string[] ...$whitelist
* #return Array
*/
public function whitelist(string ...$whitelist): Array
{
// code
}
How can I pass an array (e.g $arr = [$val1, $val2, ...]) to the function?
Note that I cannot change the function structure because it belongs to a third party class I am using in my code.

/**
* #param \string[] ...$whitelist
* #return Array
*/
public function whitelist(string ...$whitelist): Array
{
// code
}
You pass the arguments by separating them by comma, meaning the whitelist function takes n number of arguments. You are using the splat operator (https://lornajane.net/posts/2014/php-5-6-and-the-splat-operator). So, in your case it may be something like:
whitelist(...['Item 1', 'Item 2', 'Item 3']);

Related

Add a VSA (Vendor Specific Attribute) to Access-Accept reply programmatically in FreeRADIUS C module

I have a FreeRADIUS C language module that implements MOD_AUTHENTICATE and MOD_AUTHORIZE methods for custom auth purpose. I need the ability to programmatically add VSAs to the Access-Accept reply.
I have toyed a bit with radius_pair_create() and fr_pair_add() methods (see snippet below) but that didn’t yield any change to the reply content, possibly because I specified ad-hoc values that don’t exist in a vendor-specific dictionary. Or because I didn’t use them correctly.
My FreeRADIUS version is 3_0_19
Any information, pointers and, especially, syntax samples will be highly appreciated.
void test_vsa(REQUEST *request)
{
VALUE_PAIR *vp = NULL;
vp = radius_pair_create(request->reply, NULL, 18, 0);
if (vp)
{
log("Created VALUE_PAIR");
vp->vp_integer = 96;
fr_pair_add(&request->reply->vps, vp);
}
else
{
log("Failed to create VALUE_PAIR");
}
}
So first off you're writing an integer value to a string attribute, which is wrong. The only reason why the server isn't SEGVing is because the length of the VP has been left at zero, so the RADIUS encoder doesn't bother dereferencing the char * inside the pair that's meant to contain the pair's value.
fr_pair_make is the easier function to use here, as it takes both the attribute name and value as strings, so you don't need to worry about the C types.
The code snippet below should do what you want.
void test_avp(REQUEST *request)
{
VALUE_PAIR *vp = NULL;
vp = fr_pair_make(request->reply, &request->reply->vps, "Reply-Message", "Hello from FreeRADIUS", T_OP_SET);
if (vp)
{
log("Created VALUE_PAIR");
}
else
{
log("Failed to create VALUE_PAIR");
}
}
For a bit more of an explanation, lets look at the doxygen header:
/** Create a VALUE_PAIR from ASCII strings
*
* Converts an attribute string identifier (with an optional tag qualifier)
* and value string into a VALUE_PAIR.
*
* The string value is parsed according to the type of VALUE_PAIR being created.
*
* #param[in] ctx for talloc
* #param[in] vps list where the attribute will be added (optional)
* #param[in] attribute name.
* #param[in] value attribute value (may be NULL if value will be set later).
* #param[in] op to assign to new VALUE_PAIR.
* #return a new VALUE_PAIR.
*/
VALUE_PAIR *fr_pair_make(TALLOC_CTX *ctx, VALUE_PAIR **vps,
char const *attribute, char const *value, FR_TOKEN op)
ctx - This is the packet or request that the vps will belong to. If you're adding attributes to the request it should be request->packet, reply would be request->reply, control would be request.
vps - If specified, this will be which list to insert the new VP into. If this is NULL fr_pair_make will just return the pair and let you insert it into a list.
attribute - The name of the attribute as a string.
value - The value of the attribute as a string. For non-string types, fr_pair_make will attempt to perform a conversion. So, for example, passing "12345" for an integer type, will result in the integer value 12345 being written to an int field in the attribute.
op - You'll usually want to us T_OP_SET which means overwrite existing instances of the same attribute. See the T_OP_* values of FR_TOKEN and the code that uses them, if you want to understand the different operators and what they do.

How do I doxygen-document unnamed parameters of a function?

With doxygen, I'm used to write
/**
* #brief blah blah
*
* #param foo description of foo
* #param bar description of bar
* #return description of the return value
*/
int f(int foo, unsigned bar);
But what if I don't name one of the parameter? :
int f(int, unsigned bar);
How can I document this parameter when I can't refer to it by name?
Doxygen does not currently (July 2020) implement this functionality. However, a feature request has been opened on the Doxygen GitHub issues page for it:
#6926 Feature request: doc for unnamed parameters

Obtaining a list of class names with objc_getClassList in JavaScript for Automation

By using ObjC.bindFunction in JXA, we can obtain an integer result from objc_getClassList.
Does anyone understand the types and bridging issues well enough to find a route to getting a list of class name strings returned by objc_getClassList into the JavaScript for Automation JSContext ?
(The code below returns only an [Object Ref] string)
(() => {
'use strict';
ObjC.import('stdlib');
ObjC.bindFunction('CFMakeCollectable', [ 'id', [ 'void *' ] ]);
ObjC.bindFunction('objc_getClassList', ['int', ['void *', 'int']]);
var classes = Ref();
const intClasses = $.objc_getClassList(null, 0);
$.objc_getClassList(classes, intClasses);
$.CFMakeCollectable(classes);
return [intClasses, classes];
//-> [11411, [object Ref]]
})();
The objc_getClassList function is expecting us to provide it with a buffer of memory to copy the class list into. Normally, JXA would treat the return type of malloc as a C array of unsigned chars, but using bindFunction we can cast malloc's return type to a C array of pointers, and make objc_getClassList's first argument match that type. Then, it's just a matter of indexing into the buffer (of type Ref) and passing that value into class_getName.
ObjC.bindFunction('objc_getClassList', ['int', ['void**', 'int']])
ObjC.bindFunction('malloc', ['void**', ['int']])
ObjC.bindFunction('class_getName', ['char *', ['void*']])
const numClasses = $.objc_getClassList(undefined, 0)
const classes = $.malloc(8*numClasses)
$.objc_getClassList(classes, numClasses)
for (i=0; i<numClasses; i++) {
console.log("classes[" + i + "]: " + $.class_getName(classes[i]))
}

How to map a single char column in Doctrine 2

How can I map a single char column in Doctrine 2, using annotations? I would like to have a char type, instead a single char string.
You can always use the string type with the fixed option:
/**
* #Column(type="string", length=2, options={"fixed" = true})
*/
protected $country;
The above code snippet produces the following SQL:
`country` char(2) NOT NULL,
Doctrine doesn't have a CHAR type defined out of the box, however it does allow you to define custom types, which you could use to create a 'char' type to use in annotations.
The Doctrine documentation has an example of this: http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html#custom-mapping-types
You might end up providing your own full-column definition:
/**
* #Column(type="string", columnDefinition="CHAR(2) NOT NULL")
*/
protected $country = null;

Dynamic allocation in Objective-C, returning pointers

I would like to make sure the value of the pointer myFunction() returns is available, when it's not an Obj-C object.
double * vectorComponents (); //Just an example
double * vectorComponents ()
{
double componentSet[] = {1, 2, 3};
return componentSet;
}
How can I dynamically allocate these variables an then how to dealloc them. If I don't do anything it won't work. Thanks everyone.
NSLog(#":)");
You can use the C standard library functions malloc() and free():
double *vectorComponents()
{
double *componentSet = malloc(sizeof(*componentSet) * 3);
componentSet[0] = 1;
componentSet[1] = 2;
componentSet[2] = 3;
return componentSet;
}
double *comps = vectorComponents();
// do something with them, then
free(comps);
(Documentation)
Also:
If I don't do anything it won't work.
Perhaps it's worth mentioning that it didn't work because it invokes undefined behavior. componentSet in your code was a local auto-array - it's invalidated at the end of its scope (i. e. it's deallocated at the time the function returns - exactly what you wanted not to happen.)
If you return a pointer that you dynamically allocate in the function then the caller will have ownership of the object and will be required to free the value.
/**
* Returns ownership, use free to release the value when done.
*/
double * vectorComponents()
{
double *componentSet = malloc(sizeof(double) * 3);
componentSet[0] = 1.0;
componentSet[1] = 2.0;
componentSet[2] = 3.0;
return componentSet;
}
void example()
{
double *components = vectorComponents();
//use components
free(components);
}
Given your example, first question is do you really need dynamic allocation? If you just want to return the address of an array initialized inside a function you can use a static variable:
double * vectorComponents ()
{
static double componentSet[] = {1, 2, 3};
return componentSet;
}
If you do need a dynamic array then there are many ways to do it. If you compute the array you can malloc() the storage to be free()'ed later. If you wish to initialize a dynamic array, then maybe change the values, and return it you can use a static array to do that. For example:
double * vectorComponents2 ()
{
static double componentSet[] = {1, 2, 3};
double *dynamic = malloc(sizeof(componentSet));
memcpy(dynamic, componentSet, sizeof(componentSet)); // copy values
// modify contents of dynamic here if needed
return dynamic;
}
Using memcpy and a static array is shorter than setting individual values and allows the contents and size of the array to be changed easily.