Jcwyatteve's Profile

230
Points

Questions
44

Answers
40

  • Asked on July 17, 2020 in XML.

    Another way to write it (more consuming though) :

    //a[count(preceding-sibling::*)=1 and preceding-sibling::*[1][self::a]][parent::div]/.. 

    Look for an a element child of a div, with 1 preceding-sibling which is an anchor. Then get the parent.

    • 383 views
    • 2 answers
    • 0 votes
  • Asked on July 17, 2020 in XML.

    Selenium does not native support verifying text present in an XML page. Why not check with language which you’re writing automation script? If you’re doing automation with Java, you can use Java XPath Parser

    • 375 views
    • 1 answers
    • 0 votes
  • You can do

    PropertyInfo[] properties = targetDesignProject.SectionStatuses.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);               foreach (PropertyInfo property in properties)  {     var propValue = property.GetValue(targetDesignProject.SectionStatuses);      if (propValue is ProjectSectionStage)     {        property.SetValue(targetDesignProject.SectionStatuses, propValue)         // You can do this if you want        // var newPropValue = rojectSectionStage.INCOMPLETE;        // property.SetValue(targetDesignProject.SectionStatuses, newPropValue)     }  } 

    Also, you can refer to these page if you want more documentation:

    https://docs.microsoft.com/en-us/dotnet/api/system.reflection.propertyinfo.setvalue?view=netcore-3.1

    https://docs.microsoft.com/en-us/dotnet/api/system.reflection.propertyinfo.setvalue?view=netcore-3.1#System_Reflection_PropertyInfo_SetValue_System_Object_System_Object_System_Object___

    • 458 views
    • 2 answers
    • 0 votes
  • Use prepared statements and parameterized queries. These are SQL statements that are sent to and parsed by the database server separately from any parameters. This way it is impossible for an attacker to inject malicious SQL.

    You basically have two options to achieve this:

    1. Using PDO (for any supported database driver):

      $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');  $stmt->execute([ 'name' => $name ]);  foreach ($stmt as $row) {     // Do something with $row } 
    2. Using MySQLi (for MySQL):

      $stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?'); $stmt->bind_param('s', $name); // 's' specifies the variable type => 'string'  $stmt->execute();  $result = $stmt->get_result(); while ($row = $result->fetch_assoc()) {     // Do something with $row } 

    If you’re connecting to a database other than MySQL, there is a driver-specific second option that you can refer to (for example, pg_prepare() and pg_execute() for PostgreSQL). PDO is the universal option.


    Correctly setting up the connection

    Note that when using PDO to access a MySQL database real prepared statements are not used by default. To fix this you have to disable the emulation of prepared statements. An example of creating a connection using PDO is:

    $dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'password');  $dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

    In the above example the error mode isn’t strictly necessary, but it is advised to add it. This way the script will not stop with a Fatal Error when something goes wrong. And it gives the developer the chance to catch any error(s) which are thrown as PDOExceptions.

    What is mandatory, however, is the first setAttribute() line, which tells PDO to disable emulated prepared statements and use real prepared statements. This makes sure the statement and the values aren’t parsed by PHP before sending it to the MySQL server (giving a possible attacker no chance to inject malicious SQL).

    Although you can set the charset in the options of the constructor, it’s important to note that ‘older’ versions of PHP (before 5.3.6) silently ignored the charset parameter in the DSN.


    Explanation

    The SQL statement you pass to prepare is parsed and compiled by the database server. By specifying parameters (either a ? or a named parameter like :name in the example above) you tell the database engine where you want to filter on. Then when you call execute, the prepared statement is combined with the parameter values you specify.

    The important thing here is that the parameter values are combined with the compiled statement, not an SQL string. SQL injection works by tricking the script into including malicious strings when it creates SQL to send to the database. So by sending the actual SQL separately from the parameters, you limit the risk of ending up with something you didn’t intend.

    Any parameters you send when using a prepared statement will just be treated as strings (although the database engine may do some optimization so parameters may end up as numbers too, of course). In the example above, if the $name variable contains 'Sarah'; DELETE FROM employees the result would simply be a search for the string "'Sarah'; DELETE FROM employees", and you will not end up with an empty table.

    Another benefit of using prepared statements is that if you execute the same statement many times in the same session it will only be parsed and compiled once, giving you some speed gains.

    Oh, and since you asked about how to do it for an insert, here’s an example (using PDO):

    $preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)');  $preparedStatement->execute([ 'column' => $unsafeValue ]); 

    Can prepared statements be used for dynamic queries?

    While you can still use prepared statements for the query parameters, the structure of the dynamic query itself cannot be parametrized and certain query features cannot be parametrized.

    For these specific scenarios, the best thing to do is use a whitelist filter that restricts the possible values.

    // Value whitelist // $dir can only be 'DESC', otherwise it will be 'ASC' if (empty($dir) || $dir !== 'DESC') {    $dir = 'ASC'; } 
    • 1051 views
    • 28 answers
    • 0 votes
  • Asked on July 16, 2020 in Mysql.

    You can use a prepared statement to do this. The column name can’t be a variable.

    Create procedure:

    drop procedure if exists schema_change;  delimiter // create procedure schema_change(in table_name_arg VARCHAR(40), in column_name_arg VARCHAR(40)) begin     if exists(select *               from information_schema.columns               where table_schema = schema()                 and table_name = table_name_arg                 and column_name = column_name_arg) then             SELECT CONCAT('ALTER TABLE TestResults drop column ',column_name_arg) INTO @sqlv;             PREPARE stmt FROM @sqlv;             EXECUTE stmt;             DEALLOCATE PREPARE stmt;     end if; end; // delimiter ; 

    Show table before:

    MariaDB [bernd]> desc TestResults; +-------+---------+------+-----+---------+-------+ | Field | Type    | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | x     | int(11) | YES  |     | NULL    |       | | y     | int(11) | YES  |     | NULL    |       | +-------+---------+------+-----+---------+-------+ 2 rows in set (0.00 sec) 

    Call procedure:

    MariaDB [bernd]> call schema_change('TestResults', 'y'); Query OK, 0 rows affected (0.03 sec) 

    Show table after:

    MariaDB [bernd]> desc TestResults; +-------+---------+------+-----+---------+-------+ | Field | Type    | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | x     | int(11) | YES  |     | NULL    |       | +-------+---------+------+-----+---------+-------+ 1 row in set (0.00 sec)  MariaDB [bernd]> 
    • 366 views
    • 1 answers
    • 0 votes
  • MySQL won’t treat an empty string as null, simply because an empty string and null are two different things. So the message you get from MySQL isn’t weird, it’s correct.

    Nullify all empty strings in an array

    If you just want to nullify all empty strings in an array, you can create a simple function for it:

    function nullifyEmptyStrings(array $array) {     return array_map(function ($item) {          return $item !== '' ? $item : null;      }, $array); } 

    Then call it where ever/when ever you need it:

    $row = nullifyEmptyStrings($row); 

    or use it directly in the argument for the create function:

    MyModel::create(nullifyEmptyStrings($row)); 

    Here’s a demo

    Nullify specific empty strings in an array

    If you want to be able to define which array items to nullify, you can use this function:

    function nullifyEmptyArrayValues(array $array, array $keys) {     foreach ($keys as $key) {         if (array_key_exists($key, $array) && $array[$key] === '') {             $array[$key] = null;         }     }          return $array; } 

    And in your code, you first pass the array containing the data and then another array with the keys to nullify, if the values are empty:

    $row = nullifyEmptyArrayValues($row, ['some-key', 'another-key']); 

    Here’s a demo

    • 361 views
    • 1 answers
    • 0 votes
  • Asked on July 16, 2020 in Mysql.

    In addition to @don’s answer

    I assume it has something to do with the dns not properly resolving localhost. I have experienced that before, but outside of just mapping localhost to 127.0.01 in the host’s file,

    This can also be fixed by changing a value in your /etc/mysql/my.cnf file.

    It’s likely your bind-address line is

    bind-address = localhost  

    You can try changing it to

    bind-address = 127.0.0.1 

    You can also set it to 0.0.0.0 but this will expose the connection to the outside world (inc. public IP), so this is highly not recommended but will solve the problem.

    • 0 views
    • 1 answers
    • 0 votes
  • Asked on July 16, 2020 in Mysql.

    You need to refer to a column in the where clause of the delete, not the table. A table alias will help:

    DELIMITER // create trigger UpdateTrigger      after update         on reserva for each row begin     IF NEW.reserva_valida = 0 THEN         DELETE v FROM companhia_aerea.venda v         WHERE v.reserva_id = NEW.reserva_id;     END IF; end; DELIMITER ; 
    • 281 views
    • 1 answers
    • 0 votes
  • Asked on July 16, 2020 in Java Script.

    What is a Promise?

    A JavaScript Promise is an object that produces a single value, asynchronously. Data goes in, and a single value is emitted and used. Easy, straightforward way to handle incoming data.

    Promises are very eager. If we had a callback function provided to a Promise, once the Promise is resolved, the .then gets executed. If we were to demonstrate that in an API call, it would look something like this:

    fetch('my-api-goes-here')    .then(resp => resp.json()); 

    What is an Observable?

    An Observable takes in a stream of data and emits multiple bits of data over time.

    Observables are very lazy. They don’t do much until called upon. Or how we like to say in the Observable world, are "subscribed" to. To create an Observable, we create a function, and this function will return the data.

    If we were to demonstrate an Observable, it would look something like this:

    const data$ = new Observable("stuff here")  data$.subscribe(data => {   // do some stuff here }) 
    • 439 views
    • 2 answers
    • 0 votes
  • Asked on July 16, 2020 in Python.

    Brackets are used in python in three main ways

    • to define tuples
    • to group code
    • to pass arguments into a method

    In this specific case – there won’t be any difference, as this is the second case. (a) is same as a. But, if there was a comma after a – then a tuple would’ve been created – (a,). One benefit of using ( for grouping code is that you can spread it into several lines for better formatting.

    index4 = (     employees[4] ) 
    • 331 views
    • 4 answers
    • 0 votes